斜率优化DP(hdu3507)
来源:互联网 发布:csgo 手机 检视 软件 编辑:程序博客网 时间:2024/04/29 21:54
Print Article
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Problem Description
Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it to print articles. But it is too old to work for a long time and it will certainly wear and tear, so Zero use a cost to evaluate this degree.
One day Zero want to print an article which has N words, and each word i has a cost Ci to be printed. Also, Zero know that print k words in one line will cost
M is a const number.
Now Zero want to know the minimum cost in order to arrange the article perfectly.
One day Zero want to print an article which has N words, and each word i has a cost Ci to be printed. Also, Zero know that print k words in one line will cost
M is a const number.
Now Zero want to know the minimum cost in order to arrange the article perfectly.
Input
There are many test cases. For each test case, There are two numbers N and M in the first line (0 ≤ n ≤ 500000, 0 ≤ M ≤ 1000). Then, there are N numbers in the next 2 to N + 1 lines. Input are terminated by EOF.
Output
A single number, meaning the mininum cost to print the article.
Sample Input
5 559575
Sample Output
230
Author
Xnozero
Source
2010 ACM-ICPC Multi-University Training Contest(7)——Host by HIT
此题是很基础的斜率DP的入门题。
题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M让我们求这个费用的最小值。
设dp[i]表示输出前i个的最小费用,那么有如下的DP方程:
dp[i]= min{ dp[j]+(sum[i]-sum[j])^2 +M } 0<j<i
其中 sum[i]表示数字的前i项和。
相信都能理解上面的方程。
直接求解上面的方程的话复杂度是O(n^2)
对于500000的规模显然是超时的。下面讲解下如何用斜率优化DP使得复杂度降低一维。
我们首先假设在算 dp[i]时,k<j ,j点比k点优。
也就是
dp[j]+(sum[i]-sum[j])^2+M <= dp[k]+(sum[i]-sum[k])^2+M;
所谓j比k优就是DP方程里面的值更小
对上述方程进行整理很容易得到:
[(dp[j]+sum[j]*sum[j])-(dp[k]+sum[k]*sum[k])] / 2(sum[j]-sum[k]) <=sum[i].
注意整理中要考虑下正负,涉及到不等号的方向。
左边我们发现如果令:yj=dp[j]+sum[j]*sum[j] xj=2*sum[j]
那么就变成了斜率表达式:(yj-yk)/(xj-xk) <= sum[i];
而且不等式右边是递增的。
所以我们可以看出以下两点:我们令g[k,j]=(yj-yk)/(xj-xk)
第一:如果上面的不等式成立,那就说j比k优,而且随着i的增大上述不等式一定是成立的,也就是对i以后算DP值时,j都比k优。那么k就是可以淘汰的。
第二:如果 k<j<i 而且 g[k,j]>g[j,i] 那么 j 是可以淘汰的。
假设 g[j,i]<sum[i]就是i比j优,那么j没有存在的价值
相反如果 g[j,i]>sum[i] 那么同样有 g[k,j]>sum[i] 那么 k比 j优 那么 j 是可以淘汰的
所以这样相当于在维护一个下凸的图形,斜率在逐渐增大。
通过一个队列来维护。
以上转自http://www.cnblogs.com/kuangbin/archive/2012/08/26/2657650.html
下面是自己的见解
,假设k<j<i,前面几个插入呈现这样的情况,此时sum[i]<g[j,k]<g[i,j]
接下来插入i+1,有两种情况
①g[j,k]>sum[i+1],此时dp[i+1]的最小值一定为dp[k]+(sum[i]-sum[k])^2+m
②g[j,k]>sum[i+1],此时先删除k,因为k一定不是最优解
再分为两种情况,
1.g[i,j]>sum[i+1],j为最优解,无需删除
2.g[i,j]<sum[i+1],
此时先删除j,因为j一定不是最优解,依次循环
#include<bits/stdc++.h>using namespace std;const int maxn=500010;int dp[maxn],sum[maxn],q[maxn];int head,tail,n,m;// dp[i]= min{ dp[j]+M+(sum[i]-sum[j])^2 };int getUP(int j,int k){ return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]);}int getDOWN(int j,int k){ return 2*(sum[j]-sum[k]);}int getDP(int i,int j){ return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);}int main(){ while(scanf("%d%d",&n,&m)!=EOF){ for(int i=1;i<=n;i++) scanf("%d",&sum[i]); sum[0]=dp[0]=0; for(int i=1;i<=n;i++) sum[i]+=sum[i-1]; head=tail=0; q[tail++]=0; for(int i=1;i<=n;i++){ while(head+1<tail&&getUP(q[head+1],q[head])<=sum[i]*getDOWN(q[head+1],q[head])) head++; dp[i]=getDP(i,q[head]); while(head+1<tail&&getUP(i,q[tail-1])*getDOWN(q[tail-1],q[tail-2])<=getUP(q[tail-1],q[tail-2])*getDOWN(i,q[tail-1])) tail--; q[tail++]=i; } printf("%d\n",dp[n]); } return 0;}
0 0
- hdu3507斜率优化dp
- hdu3507 斜率优化dp
- 斜率优化DP(hdu3507)
- 斜率优化dp:HDU3507
- HDU3507(dp + 斜率优化dp)
- hdu3507 斜率优化dp入门
- hdu3507之斜率优化DP入门
- HDU3507--Print Article(斜率优化DP)
- [HDU3507]Print Article(斜率优化dp)
- hdu3507 Print Article(斜率优化dp)
- hdu3507 Print Article(斜率优化dp)
- hdu3507 Print Article DP+斜率优化
- 【HDU3507】Print Article-DP斜率优化入门
- [hdu3507] Print Article DP斜率优化入门
- 【HDU3507】【斜率优化DP】Print Article题解
- #HDU3507#Print Article(DP+斜率优化)
- [hdu3507] Print Article(斜率优化dp)
- HDU3507 Print Article 【斜率优化DP】
- Ubuntu下设置通过NAT方式上网(静态IP)
- 关于反射的一些姿势
- ZMQ源码分析(八)--ROUTER-DEALER & REQ-REP
- 常用正则表达式
- 使用Ant运行JUnit测试用例时,报java.lang.ClassNotFoundException: org.hamcrest.SelfDescribing的一种解决方案
- 斜率优化DP(hdu3507)
- 【iOS提高】CoreAnimation--Layer
- Kafka 安装和测试
- UVA11995 优先队列
- c#多线程与异步开发 (下)
- '加入收藏' 功能
- 2016.1.29
- 工具类——验证码
- 体绘制之光线投射算法(附源码)