Print Article[HDU 3507]

来源:互联网 发布:mt4软件kdj指标 编辑:程序博客网 时间:2024/05/20 21:22

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

(i=1kCi)2+M

M is a const number.
Now Zero want to know the minimum cost in order to arrange the article perfectly.


Input Description

There are many test cases. For each test case, There are two numbers N and M in the first line (0n500000,0M1000) . Then, there are N numbers in the next 2 to N+1 lines. Input are terminated by EOF .


Output Description

A single number, meaning the mininum cost to print the article.


Sample Input

5 5
5
9
5
7
5


Sample Output

230


I Think

fi 表示写上前 i 个数字的最小花费 , siCi 的前缀和,则 fi=min{fj+M+(sisj)2} ,时间复杂度 O(n2) ,超时。
现在考虑当 k<j<i 时,如果决策 j 比决策 k 优的条件,则

fj+M+(sisj)2fj+s2j2sisjfj+s2j(fk+s2k)2(sjsk)fk+M+(sisk)2fk+s2i2sisksi

yj=fj+s2jxj=2sj , gj,k 表示前面式子的左边,则上面的式子化为
gj,k=yjykxjxksi

对于两个决策 k<j 如果 gj,ksi,则决策 j 优于决策 k 。如果 gi,jgj,k 那么决策 j 一定不最优。


Code

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 500010;int que[Size];int a[Size];int f[Size];int s[Size];int n,m;int H,T;int x(int,int);int y(int,int);int main(){    while(scanf("%d%d",&n,&m)!=EOF){        for(int i=1;i<=n;++i){            scanf("%d",&a[i]);            s[i] = s[i-1]+a[i];        }        H = que[0] = 0;        T = 1;        for(int i=1;i<=n;++i){              while(H+1<T && y(que[H+1],que[H])<=s[i]*x(que[H+1],que[H]))                ++H;            f[i] = f[que[H]]+m+(s[i]-s[que[H]])*(s[i]-s[que[H]]);            while(H+1<T && y(i,que[T-1])*x(que[T-1],que[T-2])<=y(que[T-1],que[T-2])*x(i,que[T-1]))                --T;            que[T++] = i;        }        printf("%d\n",f[n]);    }    return 0;}int x(int i,int j){    return (s[i]-s[j])*2;}int y(int i,int j){    return f[i]+s[i]*s[i]-f[j]-s[j]*s[j];}
0 0
原创粉丝点击