hdu3507Print Article(斜率)
来源:互联网 发布:矩阵的秩8个性质及证明 编辑:程序博客网 时间:2024/05/29 08:30
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.
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 5 5 9 5 7 5
Sample Output
230
分析:
第二道斜率优化,摸索出了一点套路
说实话题目就看蒙了。。。
题意:将序列a[n]分成若干段,每段的值为(∑a[i])^2 + M. 求序列的最小值
做优化dp首先需要的就是状态转移方程
f[i]表示到第i个数的最优值
f[i]=min{f[j]+(sum[i]-sum[j])^2+m} (前一段最后一个数是j)
假设 k < j < i
f[j]的状态比k更优
则一定有
f[j]+(sum[i]-sum[j])^2+m < f[k]+(sum[i]-sum[k])^2+m
f[j]+sum[j]^2-2*sum[i]*sum[j] < f[k]+sum[k]^2-2*sum[i]*sum[k]
(f[j]+sum[j]^2)-(f[k]+sum[k]^2) < 2*sum[i]*(sum[j]-sum[k])
移项,得
((f[j]+sum[j]^2)-(f[k]+sum[k]^2))/(2*(sum[j]-sum[k])) < sum[i]
设y=f[]+sum[]^2,x=sum[]
则原式=>
y[j]-y[k]/x[j]-x[k] < sum[i]
设g(j,k)=y[j]-y[k]/x[j]-x[k]
g(j,k) < sum[i]
说明f[j]的状态比f[k]更优(横坐标更大的更优)
那我们能不能利用这个性质去掉一些状态呢
假设 k < j < i
若g(j,k)>g(j,i),那么j这个状态可以去掉
证明:
1.g(i,j) < sum[i],i比j更优
2.g(i,j) >=sum[i],则g(j,k)>g(i,j)>=sum[i],j比i优而k比j更优
这样我们一旦遇到了g(j,k)>g(j,i)就可以去掉j这种状态了,
这样我们的状态转移可以变成:
1.维护一个双端优先队列
2.维护f,在队首取元素,若g(q[tou],q[tou+1])<=sum[i],tou–
因为tou+1的状态更优,直到g(q[tou],q[tou+1])>sum[i],
就用q[tou]更新f
3.在队尾加入f[i],若g(i,q[wei])<=g(q[wei],q[wei-1]),wei–,
(g(j,k)>g(j,i)就可以去掉j这种状态了),直到g(i,q[wei])>g(q[wei],q[wei-1]),加入i
tip:
注意初始状态:
f[0]=0;
f[1]=sum[1]*sum[1]+m; //f[1]=f[0]+(sum[1]-sum[0])^2+m
wei=1; tou=0; q[wei]=1; q[tou]=0;
这里写代码片#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int N=500005;int n,m;int q[N],tou,wei,sum[N],f[N];double xl(int x,int y){ return (double)((f[x]+sum[x]*sum[x])-(f[y]+sum[y]*sum[y]))/(double)(2*f[x]-2*f[y]);}void doit(){ f[0]=0; f[1]=sum[1]*sum[1]+m; //初始状态很重要 wei=1; tou=0; q[wei]=1; q[tou]=0; for (int i=2;i<=n;i++) { while (tou<wei&&xl(q[tou],q[tou+1])<=sum[i]) tou++; f[i]=f[q[tou]]+(sum[i]-sum[q[tou]])*(sum[i]-sum[q[tou]])+m; while (tou<wei&&xl(i,q[wei])<=xl(q[wei],q[wei-1])) wei--; q[++wei]=i; } printf("%d",f[n]);}int main(){ while (~(scanf("%d%d",&n,&m))) { int u; for (int i=1;i<=n;i++) scanf("%d",&u),sum[i]=sum[i-1]+u; doit(); } return 0;}
- hdu3507Print Article(斜率)
- hdu3507Print Article (斜率dp水题)
- hdu3507Print Article【斜率优化入门题】
- hdu3507Print Article
- HDU 3507 Print Article (斜率优化)
- [HDU3507]Print Article(斜率优化dp)
- hdu3507 Print Article(斜率优化dp)
- HDU 3507:Print Article(斜率DP)
- HDOJ 3507 Print Article (斜率DP)
- [hdu3507] Print Article(斜率优化dp)
- hdu 3507 Print Article(斜率优化DP)
- hdu3507(print article)- 线性dp+斜率优化
- HDU 3507 Print Article(斜率优化DP)
- 【HDU 3507】Print Article(斜率优化dp)
- hdu 3507 Print Article(斜率优化DP)
- HDU 3507 Print Article(斜率DP入门理解)
- hdu #3507 Print Article(dp+斜率优化)
- HDOJ 3507 Print Article (斜率优化DP)
- LintCode49
- 进程通信值pipe管道
- CodeForces
- Leetcode Median of Two Sorted Arrays
- Appium官网Introduction
- hdu3507Print Article(斜率)
- JZOJ 5234. 【NOIP2017模拟8.7A组】外星人的路径
- SQL的四种连接-左外连接、右外连接、内连接、全连接、交叉连接
- kickstart笔记
- Eclipse&&idea快捷键功能
- HDU-3666 THE MATRIX PROBLEM(差分约束系统判断存在与否+特殊剪枝)
- 51Nod
- 自己写个mock_server
- 实验吧-天网管理系统【php弱类型==与===的利用】