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. C语言——第十四、十五周作业

    题目 题目一:交换最小值和最大值 1.实验代码 #include<stdio.h> int main() { ; int i , n; int a[N]; int x , y; scanf ...

  2. NetFPGA-1G-CML点亮 LED

    前言 用vivado建立工程的时候选择的型号为:XC7K325tffg676-1 在以下代码文件中,仿真与设计都没有问题.在xdc文件中的时钟约束与锁相环配置中还存在问题,没有寻找到解决办法 使用手册 ...

  3. io多路复用(一)

    sever端 1 import socket sk1 = socket.socket() sk1.bind(('127.0.0.1',8001,)) sk1.listen() sk2 = socket ...

  4. C++中文件的读写

    C++中文件的读写 在C++中如何实现文件的读写? 一.ASCII 输出 为了使用下面的方法, 你必须包含头文件<fstream.h>(译者注:在标准C++中,已经使用<fstrea ...

  5. poj 2142 The Balance

    The Balance http://poj.org/problem?id=2142 Time Limit: 5000MS   Memory Limit: 65536K       Descripti ...

  6. linux cenots7安装mysql

        1.下载mysql 下载的话先确认好版本. system:centos7 mysql:5.7 下面的版本自己选择,一般是86位的. 下载好的文件 2.上传到服务器 soft文件夹,终端也进入了 ...

  7. zookeeper 入门系列-理论基础 – zab 协议

    上一章讨论了paxos算法,把paxos推到一个很高的位置.但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的: 1. 活锁问题.在base-paxos算法中,不存在leader ...

  8. EasyUI 动态创建对话框Dialog

    // 拒绝审批通过 function rejectApproval() { // 创建填写审批意见对话框 $("<div id='reject-comment'> </di ...

  9. 使用URL访问http服务器

    一.概念定义 1.URI - 通用资源标识符 URI通常由三部分组成, 资源访问机制 存放资源的主机名 资源自身名称 如: http://www.baidu.com/html http://www.b ...

  10. hadoop2.6.0理论:hdfs、yarn、mapreduce的架构

    HDFS2的架构:负责数据的分布式存储 主从结构 主节点,可以有2个: namenode 从节点,有很多个: datanode namenode负责: 接收用户操作请求,是用户操作的入口 维护文件系统 ...