hdu3507 Print Article[斜率优化dp入门题]
Print Article
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 11761 Accepted Submission(s): 3586
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.
5
9
5
7
5
大概题意就是要输出N个数字a[N],输出的时候可以连续连续的输出,每连续输出一串,它的费用是 “这串数字和的平方加上一个常数M”。
我们设dp[i]表示输出到i的时候最少的花费,sum[i]表示从a[1]到a[i]的数字和。于是方程就是:
dp[i]=dp[j]+M+(sum[i]-sum[j])^2;
很显然这个是一个二维的。题目的数字有500000个,不用试了,二维铁定超时了。那我们就来试试斜率优化吧,看看是如何做到从O(n^2)复杂度降到O(n)的。
分析:
我们假设k<j<i。如果在j的时候决策要比在k的时候决策好,那么也是就是dp[j]+M+(sum[i]-sum[j])^2<dp[k]+M+(sum[i]-sum[k])^2。(因为是最小花费嘛,所以优就是小于)
两边移项一下,得到:(dp[j]+num[j]^2-(dp[k]+num[k]^2))/(2*(num[j]-num[k]))<sum[i]。我们把dp[j]-num[j]^2看做是yj,把2*num[j]看成是xj。
那么不就是yj-yk/xj-xk<sum[i]么? 左边是不是斜率的表示?
那么yj-yk/xj-xk<sum[i]说明了什么呢? 我们前面是不是假设j的决策比k的决策要好才得到这个表示的? 如果是的话,那么就说明g[j,k]=yj-jk/xj-xk<sum[i]代表这j的决策比k的决策要更优。
关键的来了:现在从左到右,还是设k<j<i,如果g[i,j]<g[j,k],那么j点便永远不可能成为最优解,可以直接将它踢出我们的最优解集。为什么呢?
我们假设g[i,j]<sum[i],那么就是说i点要比j点优,排除j点。
如果g[i,j]>=sum[i],那么j点此时是比i点要更优,但是同时g[j,k]>g[i,j]>sum[i]。这说明还有k点会比j点更优,同样排除j点。
排除多余的点,这便是一种优化!
接下来看看如何找最优解。
设k<j<i。
由于我们排除了g[i,j]<g[j,k]的情况,所以整个有效点集呈现一种上凸性质,即k j的斜率要大于j i的斜率。

这样,从左到右,斜率之间就是单调递减的了。当我们的最优解取得在j点的时候,那么k点不可能再取得比j点更优的解了,于是k点也可以排除。换句话说,j点之前的点全部不可能再比j点更优了,可以全部从解集中排除。
于是对于这题我们对于斜率优化做法可以总结如下:
1,用一个单调队列来维护解集。
2,假设队列中从头到尾已经有元素a b c。那么当d要入队的时候,我们维护队列的上凸性质,即如果g[d,c]<g[c,b],那么就将c点删除。直到找到g[d,x]>=g[x,y]为止,并将d点加入在该位置中。
3,求解时候,从队头开始,如果已有元素a b c,当i点要求解时,如果g[b,a]<sum[i],那么说明b点比a点更优,a点可以排除,于是a出队。最后dp[i]=getDp(q[head])。
#include<cstdio>
#define pf(x) ((x)*(x))
using namespace std;
const int N=5e5+;
int n,sum[N],q[N];
int m,f[N];
inline int gety(int j,int k){
return f[j]+pf(sum[j])-(f[k]+pf(sum[k]));
}
inline int getx(int j,int k){
return sum[j]-sum[k]<<;
}
int main(){
while(~scanf("%d%d",&n,&m)){
for(int i=;i<=n;i++) scanf("%d",sum+i),sum[i]+=sum[i-];
int h=,t=;q[t]=;
for(int i=;i<=n;i++){
for(;h<t&&gety(q[h+],q[h])<=sum[i]*getx(q[h+],q[h]);h++);
f[i]=f[q[h]]+pf(sum[i]-sum[q[h]])+m;
for(;h<t&&gety(i,q[t])*getx(q[t],q[t-])<=gety(q[t],q[t-])*getx(i,q[t]);t--);
q[++t]=i;
}
printf("%d\n",f[n]);
}
return ;
}
hdu3507 Print Article[斜率优化dp入门题]的更多相关文章
- [hdu3507 Print Article]斜率优化dp入门
题意:需要打印n个正整数,1个数要么单独打印要么和前面一个数一起打印,1次打印1组数的代价为这组数的和的平方加上常数M.求最小代价. 思路:如果令dp[i]为打印前i个数的最小代价,那么有 dp[i] ...
- HDU3507 Print Article —— 斜率优化DP
题目链接:https://vjudge.net/problem/HDU-3507 Print Article Time Limit: 9000/3000 MS (Java/Others) Mem ...
- HDU3507 Print Article(斜率优化dp)
前几天做多校,知道了这世界上存在dp的优化这样的说法,了解了四边形优化dp,所以今天顺带做一道典型的斜率优化,在百度打斜率优化dp,首先弹出来的就是下面这个网址:http://www.cnblogs. ...
- HDU3507 Print Article (斜率优化DP基础复习)
pid=3507">传送门 大意:打印一篇文章,连续打印一堆字的花费是这一堆的和的平方加上一个常数M. 首先我们写出状态转移方程 :f[i]=f[j]+(sum[i]−sum[j])2 ...
- hdu 3507 Print Article(斜率优化DP)
题目链接:hdu 3507 Print Article 题意: 每个字有一个值,现在让你分成k段打印,每段打印需要消耗的值用那个公式计算,现在让你求最小值 题解: 设dp[i]表示前i个字符需要消耗的 ...
- Print Article /// 斜率优化DP oj26302
题目大意: 经典题 数学分析 G(a,b)<sum[i]时 a优于b G(a,b)<G(b,c)<sum[i]时 b必不为最优 #include <bits/stdc++.h& ...
- 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 ...
- hdu3507 Print Article(斜率DP优化)
Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it ...
- hdu3507(初识斜率优化DP)
hdu3507 题意 给出 N 个数字,输出的时候可以选择连续的输出,每连续输出一串,它的费用是 这串数字和的平方加上一个常数 M. 分析 斜率优化dp,入门题. 参考 参考 得到 dp 方程后,发现 ...
随机推荐
- sp_replication_agent_checkup
Transact-SQL 参考sp_replication_agent_checkup 检查每个分发数据库的复制代理程序,这些复制代理程序正在运行但在指定的心跳信号间隔内没有历史记录.此存储过程在分发 ...
- [原创]解决jQuery.live在mobile safari(iphone / ipad / ipod)绑定失败的问题
解决方案: 给要使用live绑定事件的元素,添加“cursor:pointer”样式即可! 如: a,input,td{cursor:pointer;} 原文链接:http://bugs.jquery ...
- Java并发包学习一 ThreadFactory介绍
ThreadFactory翻译过来是线程工厂,顾名思义,就是用来创建线程的,它用到了工厂模式的思想.它通常和线程池一起使用,主要用来控制创建新线程时的一些行为,比如设置线程的优先级,名字等等.它是一个 ...
- vim 编辑器常用命令
vi 常用命令行 1.vi 模式 a) 一般模式: vi 处理文件时,一进入该文件,就是一般模式了. b) 编辑模式:在一般模式下可以进行删除,复制,粘贴等操作,却无法进行编辑操作.等按下‘i,I,o ...
- 移动端网页使用flexible.js加入百度联盟广告样式不一致问题解决
flexible.js是淘宝推出的一款移动端手机自适应的库,源码内容很简洁,当网页使用了该库之后,页面会在head中加入对应的页面响应式的meta标签. 当使用flexible.js的时候,引入百度联 ...
- linux下使用yum安装 mencached
1. 安装 yum -y install memcached 2. 启动memcached ./usr/bin/memcached -d -m 256 -u root -p 11211 -c 1024 ...
- Innodb表压缩过程中遇到的坑(innodb_file_format)
https://www.cnblogs.com/billyxp/p/3342969.html
- AppStore应用转让流程
可能大家都有这样的情况,给公司客户开发一个ios app的前期阶段是先发布在自己公司的开发者账户上面的,而不是直接发布在客户的开发者账号上面,这个到后期的话就有一个转让的事情,俗称“过户”. 步骤如下 ...
- Go并发编程(四)
并发基础 多进程 多线程 基于回调的非阻塞/异步IO 协程 协程 与传统的系统级线程和进程相比,协程的最大优势在于其“轻量级”,可以轻松创建上百万个而不会导致系统资源衰竭, ...
- java中类相关注意事项
下面default类就是默认修饰符的类 1.Java中调用类中属性或方法(不管是否静态属性或方法)都要在类的方法中调用,虽然这个太基础,但今天想在类中调用静态类的静态变量,不能调用: 2.Java调用 ...