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
 
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 *(sum[j]-sum[k]);
} void solve()
{
head=;
tail=;
que[tail++]=; //队列里存储的是决策 //tail处不存决策
for(int i=;i<=n;i++)
{
//从头开始找当前状态的最优决策,g[que[head+1],que[head]] < sum[i],说明que[head+1]比que[head]更优,删除que[head]
while(head+ < tail && getup(que[head+],que[head]) <= getdown(que[head+],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+<tail && getup(i,que[tail-])*getdown(que[tail-],que[tail-])<=getup(que[tail-],que[tail-])*getdown(i,que[tail-]))
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)==)
{
// init();
sum[]=;
for(int i=;i<=n;i++)
{
scanf("%d",&sum[i]);
sum[i]+=sum[i-];
}
//for(int i=1;i<=n;i++)
// printf("%lf ",sum[i]);
solve();
}
return ;
}

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

  1. HDU 3480 DP+斜率优化

    题意:给你n个数字,然后叫你从这些数字中选出m堆,使得每一堆的总和最小,一堆的总和就是这一堆中最大值减去最小值的平方,最后要使得所有堆加起来的总和最小. 思路:对这些数字排序之后,很容易想到DP解法, ...

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

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

  3. HDU 3480 DP 斜率优化 Division

    把n个数分成m段,每段的值为(MAX - MIN)2,求所能划分得到的最小值. 依然是先从小到大排个序,定义状态d(j, i)表示把前i个数划分成j段,所得到的最小值,则有状态转移方程: d(j, i ...

  4. HDU 3045 DP 斜率优化 Picnic Cows

    题意:将n个数分成若干组,每组数字的个数不少于t个,要把每组的数字减小到这组最小值,求所有数字减少的最小值. 先将这n个数从小到大排个序,可以想到一组里面的数一定是排序后相邻的. 设d(i)表示前i个 ...

  5. HDU 3507 [Print Article]DP斜率优化

    题目大意 给定一个长度为\(n(n \leqslant 500000)\)的数列,将其分割为连续的若干份,使得 $ \sum ((\sum_{i=j}^kC_i) +M) $ 最小.其中\(C_i\) ...

  6. hdu 2829 Lawrence(斜率优化DP)

    题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...

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

    4518: [Sdoi2016]征途 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 230  Solved: 156[Submit][Status][ ...

  8. 【BZOJ-3437】小P的牧场 DP + 斜率优化

    3437: 小P的牧场 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 705  Solved: 404[Submit][Status][Discuss ...

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

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8432  Solved: 3338[Submit][St ...

随机推荐

  1. 使用WaveOut API播放WAV音频文件(解决卡顿)

    虽然waveout已经过时,但是其api简单,有些时候也还是需要用到. 其实还是自己上msdn查阅相应api最靠谱,waveout也有提供暂停.设置音量等接口的,这里给个链接,需要的可以自己查找: h ...

  2. jQuery的切换函数(hover,toggle)

    1.hover:(鼠标悬停与离开事件) 一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法.这是一个自定义的方法,它为频繁使用的任务提供了一种“保持在其中”的状态. 当鼠标移动到一个匹配的 ...

  3. Notification通知创建

    Notification通知创建 由于通知是一个远程视图,所以创建通知在状态栏显示需要用到三个主要的对象: 一.PendingIntent对象,用来承载Intent对象的,Intent对象主要是定义通 ...

  4. java基础语法——方法,static关键字

    一:方法: 1.什么是方法: 通俗地讲,方法就是行为.它是完成特定功能的代码块能执行一个功能.它包含于类和对象中. 2.为什么要有方法: *提高代码的复用性. *提高效率 *利于程序维护 3.命名规则 ...

  5. 【TFS 2017 CI/CD系列 - 01】-- Agent篇

    一.环境要求: PowerShell 3.0 或者更高版本 VS2015或者更高版本 二.下载Agent: 用浏览器打开TFS,[Settings]--> [Agent Pools]--> ...

  6. burpsuite破解版

    来源:http://www.vuln.cn/8847

  7. Java和C++里面的重写/隐藏/覆盖

    首先,无关重载. 注:重载是同一个类的各个函数之间的.重写是父类子类之间的.Overload和Overwrite(也叫Override)的区别. 注意:Java里面区分重写(Override/Over ...

  8. strstr-strcat实现

    strstr 调用格式 #include <string.h> char *strstr(const char *haystack, const char *needle); 功能说明 该 ...

  9. Hadoop-异常-Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/avro/io/DatumReader

    //maven org.apache.avr 下载不完全 ,去maven   If you are using maven to build your jar, you need to add the ...

  10. nyoj473 A^B Problem (高速幂)

    题目473 题目信息 执行结果 pid=473" style="text-decoration:none; color:rgb(55,119,188)">本题排行 ...