【Foreign】动态规划 [分治][DP]
动态规划
Time Limit: 50 Sec Memory Limit: 128 MB
Description
我们想把这n个数切成恰好k段区间。之后这n个数的价值为这k段区间的价值和。
我们想让最终这n个数的价值和尽可能少。
例如6个数1,1,2,2,3,3要切成3段,一个好方法是切成[1],[1,2],[2,3,3],这样只有第三个区间有1的价值。因此这6个数的价值为1。
Input
接下来一行n个数ai表示这n个数。
Output
一个数表示答案。
Sample Input
1 2 1 2 1 2 1 2 1 2
Sample Output
HINT
Solution
首先,暴力DP非常显然,f[i][j] 表示分了 i 段,当前做到第 j 个元素的最小值。
那么 f[i][j] = f[i - 1][k] + sum(k + 1, i)。我们打一个表,发现决策具有单调性。
但是显然,对于这道题,我们不能直接二分转移来的位置,由于sum并不好求。
所以我们可以考虑运用分治。执行k次。Solve(l, r, L, R)表示 j∈[l, r],from∈[L, R]。
那么我们对于[l, r],考虑mid从[L, R]中的哪一个转移过来,假设是MidFrom。
那么由于决策单调性,所以[l, mid - 1]的决策点一定在[L, MidFrom],[mid + 1, r]的决策点一定在[MidFrom, R]。
移动两个指针now_l, now_r,维护sum即可。(复杂度我也不会证明呀QWQ)
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9 + ;
const s64 INF = 1e18; int get()
{
int res = , Q = ; char c;
while( (c = getchar()) < || c > )
if(c == '-') Q = -;
if(Q) res = c - ;
while( (c = getchar()) >= && c <= )
res = res * + c - ;
return res * Q;
} int n, k;
int a[ONE], cnt[ONE]; s64 record[ONE], f[ONE], value;
int now_l, now_r; void Move(int l, int r)
{
while(now_r < r) cnt[a[++now_r]]++, value += cnt[a[now_r]];
while(l < now_l) cnt[a[--now_l]]++, value += cnt[a[now_l]];
while(now_r > r) value -= cnt[a[now_r]], cnt[a[now_r--]]--;
while(l > now_l) value -= cnt[a[now_l]], cnt[a[now_l++]]--;
} void Solve(int l, int r, int L, int R) //j=l~r, from = L~R
{
if(l > r) return;
int mid = l + r >> , MidFrom;
s64 Ans = INF;
for(int from = L; from <= R; from++)
{
if(from >= mid) break;
Move(from + , mid);
if(f[from] + value < Ans)
Ans = f[from] + value, MidFrom = from;
}
record[mid] = Ans;
Solve(l, mid - , L, MidFrom);
Solve(mid + , r, MidFrom, R);
} int main()
{
n = get(); k = get();
for(int i = ; i <= n; i++)
a[i] = get(); for(int i = ; i <= n; i++) f[i] = INF;
f[] = ;
for(int j = ; j <= k; j++)
{
for(int i = ; i <= n; i++) cnt[i] = -;
now_l = now_r = ; value = , cnt[a[]] = ;
Solve(, n, , n - );
for(int i = ; i <= n; i++)
f[i] = record[i], record[i] = ;
}
printf("%lld", f[n]);
}
【Foreign】动态规划 [分治][DP]的更多相关文章
- 【学习笔记】动态规划—各种 DP 优化
[学习笔记]动态规划-各种 DP 优化 [大前言] 个人认为贪心,\(dp\) 是最难的,每次遇到题完全不知道该怎么办,看了题解后又瞬间恍然大悟(TAT).这篇文章也是花了我差不多一个月时间才全部完成 ...
- BZOJ 4518 [Sdoi2016]征途(分治DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4518 [题目大意] 给出一个数列,分成m段,求方差最小,答案乘上m的平方. [题解] ...
- HDU 3507 Print Article(CDQ分治+分治DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3507 [题目大意] 将长度为n的数列分段,最小化每段和的平方和. [题解] 根据题目很容易得到dp ...
- 洛谷P2634 聪聪可可 [国家集训队] 点分治/dp
正解:点分治/dp 解题报告: 传送门! 这题有两个做法,都是我不擅长的就都说下好了QAQ 首先这题一看到就会想到点分治? 也确实可以用点分治,那就直接用点分治鸭 每次求出到当前根距离余数为0,1,2 ...
- [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)
显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...
- 初探动态规划(DP)
学习qzz的命名,来写一篇关于动态规划(dp)的入门博客. 动态规划应该算是一个入门oier的坑,动态规划的抽象即神奇之处,让很多萌新 萌比. 写这篇博客的目标,就是想要用一些容易理解的方式,讲解入门 ...
- Leetcode之动态规划(DP)专题-详解983. 最低票价(Minimum Cost For Tickets)
Leetcode之动态规划(DP)专题-983. 最低票价(Minimum Cost For Tickets) 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行.在接下来的一年里,你要旅行的 ...
- Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings)
Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings) 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子 ...
- Leetcode之动态规划(DP)专题-474. 一和零(Ones and Zeroes)
Leetcode之动态规划(DP)专题-474. 一和零(Ones and Zeroes) 在计算机界中,我们总是追求用有限的资源获取最大的收益. 现在,假设你分别支配着 m 个 0 和 n 个 1. ...
随机推荐
- json对象与json字符串的区别
最近糟了这个坑,同一个方法,android和ios返回的数据不一样,一个是json字符串,另一个是json对象(至于为什么后台返回的是json对象,还没找到原因,但是我看到的后台的代码是有在返回之前给 ...
- [转帖]USB-C和Thunderbolt 3连接线你搞懂了吗?---没搞明白.
USB-C和Thunderbolt 3连接线你搞懂了吗? 2018年11月25日 07:30 6318 次阅读 稿源:威锋网 3 条评论 按照计算行业的风潮,USB Type-C 将会是下一代主流的接 ...
- java异常处理的throw和throws的区别
1. 区别 throws是用来声明一个方法可能抛出的所有异常信息,throws是将异常声明但是不处理,而是将异常往上传,谁调用我就交给谁处理.而throw则是指抛出的一个具体的异常类型. 2.分别介绍 ...
- Spring Boot 推荐的 Java 配置
在学 Spring 的过程中 , 配置文件慢慢的被注解所替代 , 现在 Spring Boot 更是推荐使用 Java 配置完全来代替配置文件 . 需要使用到的注解有 : Bean 相关 : @Con ...
- 半夜思考之查漏补缺, Spring 的 Bean 后处理器
有一篇写的是容器后处理器, 这篇是 Bean 后处理器 , 我对这个 Bean 后处理器的理解就是一个 AOP 编程 . Bean 后处理器 : 是一种特殊的 Bean , 这种 Bean 不对外提供 ...
- MySQL总结小妙招
mysql5.7版本,免登陆修改管理员密码: vim /etc/my.cnf 加入skip-grant-tables,重启MySQL 终端输入 mysql ,直接登录MySQL数据库,然后use my ...
- nodejs进程异常退出处理方法
1. 捕获uncaughtException process.on('uncaughtException', function (err) { //打印出错误 console.log(err); // ...
- 数据库之MySQL的介绍与使用20180703
/*******************************************************************************************/ 一.mysq ...
- 区间DP的思路(摘自NewErA)及自己的心得
以下为摘要 区间dp能解决的问题就是通过小区间更新大区间,最后得出指定区间的最优解 个人认为,想要用区间dp解决问题,首先要确定一个大问题能够剖分成几个相同较小问题,且小问题很容易组合成大问题,从而从 ...
- Pycharm远程连接服务器,并在本地调试服务器代码
问题描述 其实有很多教程了,我只是想记录一下设置得记录,这样就能充分利用阿里云服务器为我跑代码了... 步骤一:配置deployment 步骤二:选择远程python解释器 步骤三:将本地文件上传至远 ...