题目大意:将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 (斜率优化)的更多相关文章

  1. hdu 3507 Print Article(斜率优化DP)

    题目链接:hdu 3507 Print Article 题意: 每个字有一个值,现在让你分成k段打印,每段打印需要消耗的值用那个公式计算,现在让你求最小值 题解: 设dp[i]表示前i个字符需要消耗的 ...

  2. HDU 3507 Print Article 斜率优化

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  3. 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 ...

  4. 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 ...

  5. HDU 3507 单调队列 斜率优化

    斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方 ...

  6. ●HDU 3507 Print Article

    题链: http://acm.hdu.edu.cn/showproblem.php?pid=3507 题解: 斜率优化DP 一个入门题,就不给题解了,网上的好讲解很多的.   这里就只提一个小问题吧( ...

  7. HDU 3507 Print Article(DP+斜率优化)

     Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) ...

  8. DP(斜率优化):HDU 3507 Print Article

    Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)To ...

  9. HDU 3507 Print Article(斜率优化DP)

    题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上 ...

  10. HDU 3507 Print Article(斜率优化)

    显然的斜率优化模型 但是单调队列维护斜率单调性的时候出现了莫名的锅orz 代码 #include <cstdio> #include <algorithm> #include ...

随机推荐

  1. Ubuntu去掉命令行前用户名和主机名方法

    Ubuntu去掉命令行前用户名和主机名方法 $ vi ~/.bashrc 按a或i进入编辑模式 PS1='${debian_chroot:+(debian_chroot)}\w\$ ' 默认为 PS1 ...

  2. MySQL数据库----触发器

    触发器-trigger 触发器:监视某种情况,并触发某种操作. 使用触发器可以定制用户对表进行[增.删.改]操作时前后的行为,注意:没有查询 -- 触发器:某种程序触发了工具的运行 -- 触发器不能主 ...

  3. nginx反向代理-后端服务器组设置

    nginx服务器的反向代理时其最常用的重要功能之一,在实际工作中应用广泛,涉及的配置指令也比较多.下面会尽量详细地介绍对应的指令,及其使用状态. 反向代理一般是互联网需要向内网拉取资源,比如访问一个w ...

  4. NFS常用命令

    1.客户端查看服务端可挂载卷 showmount -t 服务端IP 2.不重启加载NFS配置文件 exportfs -avr

  5. ORM 关系对象映射 基础知识点

    优点: 1.ORM使我们通用的数据库变得更加的简单便捷. 2.可避免新手程序员写sql语句带来的性能问题. 1. 创建单表 2. 创建关键表 1). 一对一 2). 一对多 3). 多对多 创建表的语 ...

  6. 20165310_获奖感想与Java阶段性学习总结

    获奖感想与Java阶段性学习总结 一.Learning By Doing ​ 在此之前,其实我并没有想到能够成为小黄杉的第一批成员之一,喜悦之余,也感受到了许多的压力.小黄杉一方面代表了老师对于我这一 ...

  7. poj Meteor Shower - 搜索

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16313   Accepted: 4291 Description Bess ...

  8. windows下的 gvim - su'blime text 的使用

    su'blime [s2'blaim] adj. n. 崇高的, 高尚的, 令人尊敬的; 壮丽的, 宏伟的; 出众的; 崇高的人, 壮丽的事物等等. a sublime mission. a subl ...

  9. Java ArrayDeque源码剖析

    ArrayDeque 本文github地址 前言 Java里有一个叫做Stack的类,却没有叫做Queue的类(它是个接口名字).当需要使用栈时,Java已不推荐使用Stack,而是推荐使用更高效的A ...

  10. 【译】Asp.net core应用在 Kubernetes上内存使用率过高问题分析

    原文:https://blog.markvincze.com/troubleshooting-high-memory-usage-with-asp-net-core-on-kubernetes/ ps ...