HDU-3507 Print Article (斜率优化)
题目大意:将n个数分成若干个区间,每个区间的代价为区间和的平方加上一个常数m,求最小代价。
题目分析:定义状态dp(i)表示前 i 个数已经分好的最小代价,则状态转移方程为
dp(i)=min(dp(j)+(sum(j)-sum(i))^2)+m <1>。将这个方程整理一下得到:
dp(i)=min(-2*sum(i)*sum(j)+dp(j)+sum(j)^2)+sum(i)^2+m <2>。
设函数f(i)=-2*sum(i)*sum(j)+dp(j)+sum(j)^2+sum(i)^2+m <3>,则dp(i)=min(f(i))。
另k(i)=-2*sum(i),x(j)=sum(j),b(j)=dp(j)+sum(j)^2+m。
则f(i)=k(i)*x(j)+b(j),
移项得到b(j)=-k(i)*x(j)+f(i) <4>。
枚举到i 时,i 是固定的,所以,-k(i)是常量,但f(i)不是常量。j仍是变量,所以x(j)与b(j)的关系便是一元一次函数中x与y的关系,每一个 j 对应一对儿(x,y),将<4>式简记为y=k*x+f(i),这实际上得到了一个斜率为k的直线族。对于 j 对应的每对儿(x,y),f(i)都有一个取值,要使得f(i)取最小值,只需要将族中的一条直线从负无穷远处往上平移,直到遇到第一个点,这时这个点对应的 j 便是最优决策,并且这个点一定会是凸包上的一个点。
随着 i 的递增,斜率-k(i)=2*sum(i)随之递增,显然,最优决策也会随之递增。这时候,就可以用单调队列来维护一个下凸壳。
第一次做这种DP,在网上看了一些大牛的博客:
http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html(这个比较易懂)
http://blog.sina.com.cn/s/blog_508dd1e60100tvk0.html
其中,又夹杂了自己的一些理解,也不知道理解的对不对,希望您看到错误之后能不吝赐教!
代码如下:
- # include<iostream>
- # include<cstdio>
- # include<cstring>
- # include<algorithm>
- using namespace std;
- int n,m;
- int a[500005];
- int q[500005];
- int dp[500005];
- int sum[500005];
- void read(int &x)
- {
- char ch=' ';
- while(ch<'0'||ch>'9') ch=getchar();
- x=0;
- while(ch>='0'&&ch<='9'){
- x=x*10+ch-'0';
- ch=getchar();
- }
- }
- void init()
- {
- sum[0]=0;
- for(int i=1;i<=n;++i){
- read(a[i]);
- sum[i]=a[i]+sum[i-1];
- }
- }
- int getSon(int i,int j)
- {
- return dp[j]-dp[i]+(sum[j]+sum[i])*(sum[j]-sum[i]);
- }
- int getMother(int i,int j)
- {
- return 2*(sum[j]-sum[i]);
- }
- int toDp(int i,int j)
- {
- return dp[i]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);
- }
- int solve()
- {
- int head=0,tail=-1;
- q[++tail]=0;
- dp[0]=0;
- for(int i=1;i<=n;++i){
- while(head+1<=tail&&getSon(q[head],q[head+1])<=sum[i]*getMother(q[head],q[head+1]))
- ++head;
- dp[i]=toDp(q[head],i);
- while(head+1<=tail&&getSon(q[tail],i)*getMother(q[tail-1],q[tail])<=getSon(q[tail-1],q[tail])*getMother(q[tail],i))
- --tail;
- q[++tail]=i;
- }
- return dp[n];
- }
- int main()
- {
- while(~scanf("%d%d",&n,&m))
- {
- init();
- printf("%d\n",solve());
- }
- return 0;
- }
HDU-3507 Print Article (斜率优化)的更多相关文章
- hdu 3507 Print Article(斜率优化DP)
题目链接:hdu 3507 Print Article 题意: 每个字有一个值,现在让你分成k段打印,每段打印需要消耗的值用那个公式计算,现在让你求最小值 题解: 设dp[i]表示前i个字符需要消耗的 ...
- HDU 3507 Print Article 斜率优化
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- hdu 3507 Print Article —— 斜率优化DP
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3507 设 f[i],则 f[i] = f[j] + (s[i]-s[j])*(s[i]-s[j]) + m ...
- HDU 3507 - Print Article - [斜率DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3507 Zero has an old printer that doesn't work well s ...
- HDU 3507 单调队列 斜率优化
斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方 ...
- ●HDU 3507 Print Article
题链: http://acm.hdu.edu.cn/showproblem.php?pid=3507 题解: 斜率优化DP 一个入门题,就不给题解了,网上的好讲解很多的. 这里就只提一个小问题吧( ...
- HDU 3507 Print Article(DP+斜率优化)
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) ...
- DP(斜率优化):HDU 3507 Print Article
Print Article Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)To ...
- HDU 3507 Print Article(斜率优化DP)
题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...
- HDU 3507 Print Article(斜率优化)
显然的斜率优化模型 但是单调队列维护斜率单调性的时候出现了莫名的锅orz 代码 #include <cstdio> #include <algorithm> #include ...
随机推荐
- ThinkPHP内置日志记录
ThinkPHP内置日志记录日志记录http://document.thinkphp.cn/manual_3_2.html#log 日志的处理工作是由系统自动进行的,在开启日志记录的情况下,会记录下允 ...
- Python3 pip出现Fatal error in launcher: Unable to create process using '"'
Python3 pip出现Fatal error in launcher: Unable to create process using '"' 问题分析: 先python2又安装了pyth ...
- 20145127 《Java程序设计》第五次实验报告
实验简述: 在本周,我们进行了Java的第五次试验,本次实验的主要内容是结对编程.本次实验的大体过程是: 1.先进行Java的客户端与服务端的代码编写.结对是两个人,一人负责客户端,一人负责服务端. ...
- 20145333茹翔 Exp5 Adobe阅读器漏洞攻击
20145333茹翔 Exp5 Adobe阅读器漏洞攻击 实验过程 主机为kali的ip地址为:192.168.1.111.靶机windows xp 的ip地址为:192.168.1.110 使用命令 ...
- Spark On YARN 分布式集群安装
一.导读 最近开始学习大数据分析,说到大数据分析,就必须提到Hadoop与Spark.要研究大数据分析,就必须安装这两个软件,特此记录一下安装过程.Hadoop使用V2版本,Hadoop有单机.伪分布 ...
- 安装Qt5.9
目前,作为一个重量级编程开发工具,Qt 已经正式发布了 5.9.0 版本.相比之前的 5.7,5.8 版本,新版本在性能和功能上有了大幅改善和提高,并由此获得了官方的明确表态:这将是继 5.6 之后的 ...
- 用Python为iOS和Android写跨平台的应用
首先保证安装了最新的python(当前安装的是python3.6) 一.安装Kivy :python -m pip install --upgrade pip wheel setuptools pyt ...
- 《算法竞赛入门经典》习题及反思 -<2>
数组 Master-Mind Hints,Uva 340 题目:给定答案序列和用户猜的序列,统计有多少数字对应正确(A),有多少数字在两个序列都出现过但位置不对. 输入包括多组数据.每组输入第一行为序 ...
- BZOJ 1015: [JSOI2008]星球大战starwar(并查集求连通块+离线处理)
http://www.lydsy.com/JudgeOnline/problem.php?id=1015 题意: 思路:好题啊!!! 这道题目需要离线处理,先把所有要删的点给保存下来,然后逆序加点,这 ...
- 肿瘤基因组学数据库终结者:cBioPortal---转载
转载自:http://blog.sciencenet.cn/blog-1509670-1000479.html 随着芯片和高通量测序技术的广泛应用,在肿瘤研究领域积累了越来越多的基因组学数据,特别是像 ...