【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. ...
随机推荐
- MiniUI框架合并单元格
在项目中遇到合并单元格的问题,所以总结一下. 用的是miniUI框架,所以只谈miniUI中的单元格合并. (1)必须添加onLoad="onLoad" (2)需要在JS中进行单元 ...
- [转帖]剖析淘宝TDDL(TAOBAO DISTRIBUTE DATA LAYER)
剖析淘宝TDDL(TAOBAO DISTRIBUTE DATA LAYER) 博客分类: 原博客地址: http://qq85609655.iteye.com/blog/2035176 distrib ...
- SQL查找删除重复行
本文讲述如何查找数据库里重复的行.这是初学者十分普遍遇到的问题.方法也很简单.这个问题还可以有其他演变,例如,如何查找“两字段重复的行”(#mysql IRC 频道问到的问题) 如何查找重复行 第一步 ...
- Java IO流学习总结 - BIO
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据 ...
- Matplotlib风羽自定义
[前言]对于气象专业的小学生来说,风场是预报重要的参考数据,我们所知的风羽有四种:短线代表风速2m/s,长线代表风速4m/s,空心三角代表风速20m/s,实心三角代表风速50m/s.而matplotl ...
- Discrete Square Roots UVALive - 4270(拓展欧几里得)
a≡b(mod n)的含义是“a和b除以n的余数相同”,其充要条件是“a-b是n的整数倍”: 求所有满足条件r^2=x(mod m)的r 题目已经给定了一个初始的r,x,m #include < ...
- USACO Section 1.5 Number Triangles 解题报告
题目 题目描述 现在有一个数字三角形,第一行有一个数字,第二行有两个数字,以此类推...,现在从第一行开始累加,每次在一个节点累加完之后,下一个节点必须是它的左下方的那个节点或者是右下方那个节点,一直 ...
- 【BZOJ4820】【SDOI2017】硬币游戏
Description Solution 设当前走出了一个不匹配任何字符串的串\(S\). 若在\(S\)后随机增添\(m\)个字符,单看这些字符而言,这\(m\)个字符匹配到每个玩家的字符串的概 ...
- 【BZOJ3309】DZY Loves Math 解题报告
[BZOJ3309]DZY Loves Math Description 对于正整数\(n\),定义\(f(n)\)为\(n\)所含质因子的最大幂指数.例如\(f(1960)=f(2^3×5^1×7^ ...
- Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)
Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列) Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺 ...