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

题目大意

将一个序列分为若干段,每段代价为该段和平方+常数M,求代价和最小。

题解

斜率优化$DP$。

考虑朴素的做法,我们令$f[i]$表示前$i$位的最小代价和。

显然我们有转移方程:

f[i]=f[j]+sqr(sum[i]-sum[j])+m; //j>0&&j<i,sum[i]=∑a[i]

显然这是一个$O(n^2)$的做法,对于$500000$的数据肯定过不去。

可以发现,我们枚举每个$i$时会不断重复遍历相同的元素,显然冗余的遍历是可以略去的。

用数据结构优化,为了找到最值,我们容易想到单调队列。

由刚才那个式子,我们拆开:

f[i]=f[j]+sqr(sum[i]-sum[j])+m
<=>f[i]=f[j]+sqr(sum[i])+sqr(sum[j])-*sum[i]*sum[j]+m
<=>f[i]= f[j]+sqr(sum[j])+m +sqr(sum[i])-*sum[i]*sum[j] (*)

我们发现$(*)$式的右边的前面一个部分是与$i$无关的,可是后面一个部分,即

-*sum[i]*sum[j]

中的$i$,$j$杂糅在了一起,显然普通的单调队列行不通了。

我们令$k<j<i$,假设计算$f[i]$时,$j$处的值比$k$处优,显然我们会有:

f[j]+sqr(sum[i]-sum[j])+M <= f[k]+sqr(sum[i]-sum[k])+M;

拆开,化简:

((f[j]+sum[j]*sum[j])-(f[k]+sum[k]*sum[k])) / (sum[j]-sum[k]) <=sum[i]

这时,我们发现,式子只有右边与$i$有关了,我们可以考虑拿左边的部分放到队列里面。

我们不妨令

yj=(f[j]+sum[j]*sum[j]),yk=(f[k]+sum[k]*sum[k]),xj=*sum[j],xk=*sum[k]
Δy=yj-yk,Δx=xj-xk

那么就变成了斜率表达式:

Δy/Δx <= sum[i];

而且不等式右边是递增的。

所以我们可以看出以下两点:我们令

g[k,j]=Δy/Δx

第一:如果上面的不等式成立,那就说$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$是可以淘汰的,所以这样相当于在维护一个下凸的图形,斜率在逐渐增大。

通过一个单调队列来维护下凸壳。

 #include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
#define RE register
#define IL inline
#define sqr(x) (x*x)
#define deltax(j,k) (2*(sum[j]-sum[k]))
#define deltay(j,k) ((f[j]+sqr(sum[j]))-(f[k]+sqr(sum[k])))
using namespace std;
const int N=; IL int Read(); int n,m;
int sum[N+];
int q[N+],head,tail;
int f[N+]; int main()
{
while (~scanf("%d%d",&n,&m))
{
for (RE int i=;i<=n;i++) sum[i]=sum[i-]+Read(),f[i]=;
head=tail=;
q[tail++]=;
for (RE int i=;i<=n;i++)
{
while (head<tail-)
if (deltay(q[head+],q[head])<=sum[i]*deltax(q[head+],q[head])) head++;
else break;
int x=sum[i]-sum[q[head]];
f[i]=f[q[head]]+sqr(x)+m;
while (head<tail-)
if (deltay(q[tail-],q[tail-])*deltax(i,q[tail-])>=deltax(q[tail-],q[tail-])*deltay(i,q[tail-])) tail--;
else break;
q[tail++]=i;
}
printf("%d\n",f[n]);
}
return ;
} IL int Read()
{
int sum=;
char c=getchar();
while (c<''||c>'') c=getchar();
while (c>=''&&c<='') sum=sum*+c-'',c=getchar();
return sum;
}

[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+斜率优化)

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

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

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

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

  6. HDU 3507 Print Article(CDQ分治+分治DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3507 [题目大意] 将长度为n的数列分段,最小化每段和的平方和. [题解] 根据题目很容易得到dp ...

  7. ●HDU 3507 Print Article

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

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

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

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

随机推荐

  1. Beta第四天

    听说

  2. 每日冲刺报告——Day2(Java-Team)

    第二天报告(11.3  周五) 团队:Java-Team 成员: 章辉宇(284) 吴政楠(286) 陈阳(PM:288) 韩华颂(142) 胡志权(143) github地址:https://git ...

  3. Bate敏捷冲刺每日报告--day4

    1 团队介绍 团队组成: PM:齐爽爽(258) 小组成员:马帅(248),何健(267),蔡凯峰(285)  Git链接:https://github.com/WHUSE2017/C-team 2 ...

  4. python 实现cm批量上传

    import requests import json import time import random url = 'http://cm.admin.xxxx.com/customer/aj_ad ...

  5. 2017-2018-1 我爱学Java 第四五周 作业

    <打地鼠>Android游戏--需求规格说明书 工作流程 组员分工及工作量比例 <需求规格说明书>的码云链接 总结与反思 参考资料 工作流程 小组成员预先参考蓝墨云班课第八周中 ...

  6. Beta集合

    Beta冲刺day1 Beta冲刺day2 Beta冲刺day3 Beta冲刺day4 Beta冲刺day5 Beta冲刺day6 Beta冲刺day7 测试总结 总结合集 Beta预备

  7. 在windows环境下安装redis和phpredis的扩展

    在windows环境下安装redis和phpredis的扩展 1.首先配置php: 需要在windows的集成环境中找到php的扩展文件夹,ext,然后在网上寻找自己的php对应的.dll文件 比如说 ...

  8. js进度条小事例

    <style> #div1{width: 500px;height: 20px;border: 1px solid gray;} #div2{height: 20px;width: 0px ...

  9. Python内置函数(29)——slice

    英文文档: class slice(stop) class slice(start, stop[, step]) Return a slice object representing the set ...

  10. php程序报错:PHP Core Warning/cannot open shared object file: No such file or directory

    今天开发调试程序的时候报错了,现象是有时候刷新会出现如下图: 这种主要是找不到共享库文件,即.so文件,网上主要有3种解决方法: 1. 用ln将需要的so文件链接到/usr/lib或者/lib这两个默 ...