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 ...
随机推荐
- 简化document.createElement("div")动态生成层方法
我们在WEB开发时,很多时候往往需要我们 JavaScript 来动态建立 html 元素,动态的设置相关的属性.比方说我们想要建立一個 div 层,则可以使用以下代码实现. 一.直接建立functi ...
- mysql jdbc性能优化之mybatis/callablestatement调用存储过程mysql jdbc产生不必要的元数据查询(已解决,cpu负载减少20%)
INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProce ...
- 定制django admin页面的跳转
在django admin的 change_view, add_view和delete_view页面,如果想让页面完成操作后跳转到我们想去的url,该怎么做 默认django admin会跳转到ch ...
- centos下gitlab私服完整安装部署(nginx+MySQL+redis+gitlab-ce+gitlab-shell+)
系统环境cat /etc/redhat-release CentOS release 6.8 (Final) nginx -vnginx version: nginx/1.9.15 redis-cli ...
- QTQuick控件基础(3)视图
1.spliteview 2.stackview ApplicationWindow {visible: truewidth: 640height: 480MouseArea{anchors.fill ...
- 20145329 《网络对抗技术》Web安全基础实践
实践的目标 理解常用网络攻击技术的基本原理.Webgoat实践下相关实验:SQL注入攻击.XSS攻击.CSRF攻击. 实验后回答问题 (1)SQL注入攻击原理,如何防御 攻击原理 SQL注入即是指we ...
- C# 获取当前IIS请求地址
using System;using System.Collections.Generic;using System.Linq;using System.Web; /// <summary> ...
- weka中算法说明[转]
1) 数据输入和输出WOW():查看Weka函数的参数.Weka_control():设置Weka函数的参数.read.arff():读Weka Attribute-Relation File For ...
- js 注意点
1.var // 反例 myname = "global"; // 全局变量 function func() { alert(myname); // "undefined ...
- HDU 2242 考研路茫茫——空调教室(边双连通分量+树形dp+重边标号)
http://acm.hdu.edu.cn/showproblem.php?pid=2242 题意: 思路:首先求一下双连通分量,如果只有一个双连通分量,那么无论断哪根管子,图还是连通的. 最后只需要 ...