hdu 3507(DP+斜率优化)

Print Article

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 6653    Accepted Submission(s): 2054

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

Author

Xnozero

Source

2010 ACM-ICPC Multi-University Training Contest(7)——Host by HIT

Recommend

zhengfeng   |   We have carefully selected several similar problems for you:  3501 3504 3505 3498 3503

此题是很基础的斜率优化DP

题目描述: 给你一些字,你可以选择每次打印一个或者几个字,每次打印的费用是(ci+c(i+1)+c(i+2)+....)^2+m;

c[i]代表每个字的费用;

设dp[i]代表打印前i个字所需的最少费用,dp[i]=min(dp[j]+(sum[i]-sum[j])^2,dp[i]);

由于n的范围是500000,那么25*10^10,肯定会超时;

可以采用斜率优化:

我们首先假设在算 dp[i]时,k<j ,j点比k点优。

也就是

dp[j]+(sum[i]-sum[j])^2+M <= dp[k]+(sum[i]-sum[k])^2+M;

所谓j比k优就是DP方程里面的值更小

对上述方程进行整理很容易得到:

[(dp[j]+sum[j]*sum[j])-(dp[k]+sum[k]*sum[k])] / 2(sum[j]-sum[k]) <=sum[i].

注意整理中要考虑下正负,涉及到不等号的方向。

左边我们发现如果令:yj=dp[j]+sum[j]*sum[j]   xj=2*sum[j]

那么就变成了斜率表达式:(yj-yk)/(xj-xk) <= sum[i];

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

所以我们可以看出以下两点:我们令g[k,j]=(yj-yk)/(xj-xk)

第一:如果上面的不等式成立,那就说j比k优,而且随着i的增大上述不等式一定是成立的,也就是对i以后算DP值时,j都比k优。那么k就是可以淘汰的。

如果不成立,那就说明k比j优,但是随着i的增加sum[i]增加,j始终会替换掉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 是可以淘汰

所以这样相当于在维护一个下凸的图形,斜率在逐渐增大。

通过一个队列来维护。

初始化队列:head=0,tail=0;que[tail++]=0;表示tail处不存决策。

于是对于这题我们对于斜率优化做法可以总结如下:

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 <iostream>
#include <cstdio>
#include <string.h>
#include <math.h>
#define maxn  500010
#define  LL int
using namespace std;

LL  sum[maxn],dp[maxn];
int que[maxn];
int head,tail;
int n;
LL  m;
int getdp(int i,int j)
{
    return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);
}

int getup(int j,int k) //yj-yk部分
{
    return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]);
}
int getdown(int j,int  k)
{
    return 2*(sum[j]-sum[k]);
}

void  solve()
{
    head=0;
    tail=0;
    que[tail++]=0;  //队列里存储的是决策   //tail处不存决策
    for(int i=1;i<=n;i++)
    {
        //从头开始找当前状态的最优决策,g[que[head+1],que[head]] <= sum[i],说明que[head+1]比que[head]更优,删除que[head]
       while(head+1 < tail && getup(que[head+1],que[head]) < getdown(que[head+1],que[head]) * sum[i] )
            head++;   //注意写成相乘,不然要考虑除数是否为负数
        dp[i]=getdp(i,que[head]);

    //从尾往前,加入当前状态,如果g[i,que[tail]] <= g[que[tail],que[tail-1]] ,可以排除que[tail]
       /* while(head+1 <tail && getup(i,que[tail-1]) * getdown(que[tail-1],que[tail-2]) <= getup(que[tail-1],que[tail-2])*getdown(i,que[tail-1])))
        {
           tail--;  //看到为什么RE了吗?笨蛋,括号打错了
        }*/
         while(head+1<tail && getup(i,que[tail-1])*getdown(que[tail-1],que[tail-2])<getup(que[tail-1],que[tail-2])*getdown(i,que[tail-1]))
                    tail--;
        que[tail++]=i;
    }
    /*for(int i=1;i<=n;i++)
    printf("%.0lf ",dp[i]);*/
    printf("%d\n",dp[n]);
}
int main()
{

    while(scanf("%d%d",&n,&m)==2)
    {
   // init();
    sum[0]=0;
    for(int i=1;i<=n;i++)
    {
    scanf("%d",&sum[i]);
    sum[i]+=sum[i-1];
    }
//for(int i=1;i<=n;i++)
// printf("%lf ",sum[i]);
    solve();
    }
return 0;
}

  

时间: 2024-08-02 11:02:12

hdu 3507(DP+斜率优化)的相关文章

Print Article hdu 3507 一道斜率优化DP 表示是基础题,但对我来说很难

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 4990    Accepted Submission(s): 1509 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antique

HDU 3480 DP 斜率优化 Division

把n个数分成m段,每段的值为(MAX - MIN)2,求所能划分得到的最小值. 依然是先从小到大排个序,定义状态d(j, i)表示把前i个数划分成j段,所得到的最小值,则有状态转移方程: d(j, i) = min { d(j-1, k) + (ai - ak+1)2 | 0 ≤ k < i } 设 l < k < i,且由k转移得到的状态比由l转移得到的状态更优. 有不等式: 整理成斜率形式: 后面的就可以相当于套模板了,不过这里要用滚动数组优化一下空间. 1 #include <

HDU 3045 DP 斜率优化 Picnic Cows

题意:将n个数分成若干组,每组数字的个数不少于t个,要把每组的数字减小到这组最小值,求所有数字减少的最小值. 先将这n个数从小到大排个序,可以想到一组里面的数一定是排序后相邻的. 设d(i)表示前i个数分完组以后减少的最小值,考虑j~i为一组,则有状态转移方程 还是一样的处理方法,设k < j ≤ i - t,且j~i为一组的值比k~i为一组的值更优. 则有不等式: 化简,把i分离出来,整理成斜率的形式: 写到这里就应该很清楚地能够看出来X和Y的表达式了. 1 #include <iostre

学渣乱搞系列之dp斜率优化

学渣乱搞系列之dp斜率优化 By 狂徒归来 貌似dp的斜率优化一直很难搞啊,尤其是像我这种数学很挫的学渣,压根不懂什么凸包,什么上凸下凸的,哎...说多了都是泪,跟wdd讨论了下,得出一些结论.本文很大部分参考了大神Accept的文章,不过此神貌似早已绝迹江湖,这篇文章写得好,也写得很差,前半部分叙述得很好,可是关键,关键部分说得很乱,有些许错误,很多大神都进行了评论指出,但是大神Accept貌似没有修改的意思,故重新总结下,以便自己以后查阅和复习啊. 下面看一个例题Print Article.

BZOJ 1096: [ZJOI2007]仓库建设(DP+斜率优化)

[ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏.由于地形的不同,在不同工厂建立仓库的费用可能是不同的.第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci.对于没有建立仓库的工厂,其

【BZOJ-4518】征途 DP + 斜率优化

4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 230  Solved: 156[Submit][Status][Discuss] Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜.所以,一段路必须在同一天中走完. Pine希望每一天走的路长度尽可能相近,所以他

Covered Walkway(HDU4258,dp斜率优化)

Covered Walkway Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Your university wants to build a new walkway, and they want at least part of it to be covered. There are certain points which

【BZOJ-1010】玩具装箱toy DP + 斜率优化

1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8432  Solved: 3338[Submit][Status][Discuss] Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P

DP 斜率优化题目/决策单调性题目

斜率优化 冬令营讲到了dp斜率优化后瞎写了一些斜率优化,因为毕竟上次写是老早以前了,当时对这个并不是很理解,现在有一点数学基础,稍微好一点了. 瞎找的斜率优化题,可能有点太水了,我这种这么菜的人竟然都切得那么快.可能难度不够,因为有个y坐标不单调要套个平衡树的我是真不会,这个嘛以后再说了. 1.hdu3507 Print Article 给定非负数列,划成若干块,每块价值是左边那玩意儿.求总权值min. 这个自己写写就可以搞出来了吧,现在看真心不难,除非数值有负的..那个要平衡树,现在写不动.