hdu 3507 斜率优化dp

来源:互联网 发布:链家地产还交端口费啊 编辑:程序博客网 时间:2024/06/04 19:43

很详细的题解

对斜率优化dp很好的总结

注意下那里面的上凸应该是下凸,还有就是一定要满足sum【i】和i都是单调的时候才能用这个斜率优化,具体的也不是很懂,要证明的。
斜率优化大致步骤就是把dp方程写出来,化简成y=kx+b(k是常数,不含j,y和x都是含有j的)的样子,好像一般b都是要求的东西,然后把斜率写出来,然后就都是套路了。

几乎一样的代码。。

#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <deque>using namespace std;typedef long long LL;const int maxn=500005;int L,R,n,m;int s[maxn];int q[maxn];int dp[maxn];int getDP(int i,int j){    return dp[j]+m+(s[i]-s[j])*(s[i]-s[j]);}int UP(int j,int k){    return dp[j]+s[j]*s[j]-dp[k]-s[k]*s[k];}int DOWN(int j,int k){    return 2*(s[j]-s[k]);}int main(){    while(scanf("%d%d",&n,&m)==2){    s[0]=0;    L=0;    R=0;    memset(dp,0,sizeof(dp));    memset(q,0,sizeof(q));    for(int i=1;i<=n;i++){        int t;        scanf("%d",&t);        s[i]=s[i-1]+t;    }    for(int i=1;i<=n;i++){        while(L<R&&UP(q[L+1],q[L])<=s[i]*DOWN(q[L+1],q[L])){            L++;        }        dp[i]=getDP(i,q[L]);        while(L<R&&UP(q[R],q[R-1])*DOWN(i,q[R])>=UP(i,q[R])*DOWN(q[R],q[R-1])){            R--;        }        q[++R]=i;    }    printf("%d\n",dp[n]);    }    return 0;}
0 0
原创粉丝点击