不好理解,先多做几个再看

此题是很基础的斜率DP的入门题。

题意很清楚,就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M

让我们求这个费用的最小值。

设dp[i]表示输出前i个的最小费用,那么有如下的DP方程:

dp[i]= min{ dp[j]+(sum[i]-sum[j])^2 +M }  0<j<i

其中 sum[i]表示数字的前i项和。

相信都能理解上面的方程。

直接求解上面的方程的话复杂度是O(n^2)

对于500000的规模显然是超时的。下面讲解下如何用斜率优化DP使得复杂度降低一维。

我们首先假设在算 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   而且 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 是可以淘汰的

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

通过一个队列来维护。

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

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])。

 /*
HDU 3507 */ #include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
const int MAXN=; int dp[MAXN];
int q[MAXN];//队列
int sum[MAXN]; int head,tail,n,m;
// dp[i]= min{ dp[j]+M+(sum[i]-sum[j])^2 };
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]);
} int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&m)==)
{
for(int i=;i<=n;i++)
scanf("%d",&sum[i]);
sum[]=dp[]=;
for(int i=;i<=n;i++)
sum[i]+=sum[i-];
head=tail=;
q[tail++]=;
for(int i=;i<=n;i++)
{
//把斜率转成相乘,注意顺序,否则不等号方向会改变的
while(head+<tail && getUP(q[head+],q[head])<=sum[i]*getDOWN(q[head+],q[head]))
head++;
dp[i]=getDP(i,q[head]);
while(head+<tail && getUP(i,q[tail-])*getDOWN(q[tail-],q[tail-])<=getUP(q[tail-],q[tail-])*getDOWN(i,q[tail-]))
tail--;
q[tail++]=i;
}
printf("%d\n",dp[n]);
}
return ;
}

hdu 3507 斜率dp的更多相关文章

  1. B - Lawrence HDU - 2829 斜率dp dp转移方程不好写

    B - Lawrence HDU - 2829 这个题目我觉得很难,难在这个dp方程不会写. 看了网上的题解,看了很久才理解这个dp转移方程 dp[i][j] 表示前面1~j 位并且以 j 结尾分成了 ...

  2. D - Pearls HDU - 1300 斜率dp+二分

    D - Pearls HDU - 1300 这个题目也是一个比较裸的斜率dp,依照之前可以推一下这个公式,这个很好推 这个注意题目已经按照价格升序排列序,所以还是前缀和还是单调的. sum[i] 表示 ...

  3. hdu 2829 斜率DP

    思路:dp[i][x]=dp[j][x-1]+val[i]-val[j]-sum[j]*sum[i]+sum[j]*sum[j]; 其中val[i]表示1~~i是一段的权值. 然后就是普通斜率dp做法 ...

  4. Print Article HDU - 3507 -斜率优化DP

    思路 : 1,用一个单调队列来维护解集. 2,假设队列中从头到尾已经有元素a b c.那么当d要入队的时候,我们维护队列的下凸性质, 即如果g[d,c]<g[c,b],那么就将c点删除.直到找到 ...

  5. HDU 3507 斜率优化dp

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

  6. HDU 3507斜率优化dp

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

  7. HDU 3507 斜率优化 DP Print Article

    在kuangbin巨巨博客上学的. #include <iostream> #include <cstdio> #include <cstring> #includ ...

  8. hdu 3507 斜率优化

    我的第一道斜率优化. 就这道题而言,写出原始的方程: dp[i] = min{ dp[j] + (sum[i]-sum[j])2  + M | j in [0,i) } O(n^2)的复杂度肯定超时, ...

  9. HDU 3480 斜率dp

    Division Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 999999/400000 K (Java/Others)Total ...

随机推荐

  1. textView中判断文本长度,自定义表情长度为1,emoj表情长度为1,输入限制

      static const int MAX_LIMIT_NUMS = 100; /**< 输入个数限制 */ // self.inputNumberTipsLabel 控制器的view上一个用 ...

  2. C语言的一点操作(学习笔记)

    #include <stdio.h> #define LENTEST 100 // 采取逐步删除的方法求的素数 //先假设1-100都是素数,然后剔除2的倍数, //3的倍数,直到剔除所有 ...

  3. CDNJS:使用JavaScript CDN加速网站载入速度

    先介绍一下: 内容传递网络(CDN)或者叫内容分发网络,他的作用是给不同区域的访客以其最快的网速.比如,你的网站是开在美国的,但很多访客来自中国,无疑他们会觉得速度很慢,那么,怎么为他们提速呢?简单来 ...

  4. Python列表基础

    ==========列表基础=========== 列表中的数据是可以被修改的.字典,元组,集合是不能被修改的. >>> li1=['3edf','dafdas'] >> ...

  5. TCP协议漏洞影响大量Linux设备

    导读 本周三在得州奥斯丁举行的 USENIX 安全研讨会上,加州大学河滨分校研究生 Yue Cao 将报告一个严重的TCP协议边信道漏洞(PDF),该漏洞允许攻击者远程劫持任意两主机之间的会话.该漏洞 ...

  6. weblogic <BEA-000438>

    现在创建域并启动服务器, 或许会发现如下提示的错误信息:<Error> <Socket> <BEA-000438> <Unable to load perfo ...

  7. hiho一下 第九十六周 数论五·欧拉函数

    题目1 : 数论五·欧拉函数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho有时候会用密码写信来互相联系,他们用了一个很大的数当做密钥.小Hi和小Ho约定 ...

  8. Jackson 框架,轻易转换JSON

    Jackson 框架,轻易转换JSON Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json.xml转换成Java对象. 前面有介绍过json-lib这个框架,在 ...

  9. 破解TP-Link路由-嗅探PPPoE拨号密码

    如果你平时都使用路由器直接上网,那么你还记得你的宽带(ADSL)帐户名和密码吗?忘记密码后又该如何找回呢?别急,本文带你一同找回遗忘的ADSL密码.1.安全性较差的路由器(例如腾达的某些路由器):这里 ...

  10. Ubuntu 更改文件夹权限及chmod详细用法

    转自: http://blog.chinaunix.net/uid-21880738-id-1813031.html 对Document/目录下的所有子文件与子目录执行相同的权限变更: Documen ...