码迷,mamicode.com
首页 > 其他好文 > 详细

[HNOI2008]玩具装箱toy(dp+斜率优化)

时间:2015-06-29 14:53:34      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:动态规划   斜率优化   算法   

    斜率优化问题一般都是决策单调问题。对于这题可以证明单调决策。

令sum[i]=sigma(c [k] ) 1<=k<=i  ,  f[i]=sum[i]+i ,  c=L+1;

 首先我们可以写出转移方程  dp[i] = min( dp[j] + (f[i]-f[j]-c)^2 )  。令决策j1<j2,若决策j2更优有

 dp[j2]+(f[i]-f[j2]-c)^2<=dp[j1]+(f[i]-f[j1]-c)^2

可以得带 ((dp[j2]+f[j2]^2)-(dp[j1]+f[j1]^2)  )/(f[j2]-f[j1])<2*(f[i]-c)。

优于f[i]是递增的,所以对于t>i的点,决策j2总是比j1更优,那么j1实际上可以从决策集合中删除。后面的就可以用一个队列维护了。



<span style="font-size:14px;">#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int inf  = 0x3fffffff;
const int mmax =50010;
LL C[mmax];
LL L,c;
LL sum[mmax],f[mmax],dp[mmax];
LL sqr(LL x)
{
    return x*x;
}
double G(int x)
{
    return 1.0*f[x]*f[x]+dp[x];
}
double S(int x)
{
    return 2.0*f[x];
}
void calc(int i,int j)
{
    dp[i]=dp[j]+sqr(f[i]-f[j]-c);
}
int Q[mmax];
int main()
{
    int n;
    while(cin>>n>>L)
    {
        c=L+1;
        sum[0]=0;
        f[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&C[i]);
            sum[i]=sum[i-1]+C[i];
            f[i]=sum[i]+i;
        }
        int head=0,tail=-1;
        dp[0]=0;
        Q[++tail]=0;
        for(int i=1;i<=n;i++)
        {
            while(head<tail)
            {
                double tmp=1.0*(G(Q[head+1])-G(Q[head]))/(S(Q[head+1])-S(Q[head]));
                if(tmp<=f[i]-c)
                    head++;
                else
                    break;
            }
            calc(i,Q[head]);
            while(head<tail)
            {
                double tmp1=1.0*(G(Q[tail])-G(Q[tail-1]))/(S(Q[tail])-S(Q[tail-1]));
                double tmp2=1.0*(G(i)-G(Q[tail]))/(S(i)-S(Q[tail]));
                if(tmp1>=tmp2)
                    tail--;
                else
                    break;
            }
            Q[++tail]=i;
        }

        printf("%lld\n",dp[n]);

    }
    return 0;
}
</span>


[HNOI2008]玩具装箱toy(dp+斜率优化)

标签:动态规划   斜率优化   算法   

原文地址:http://blog.csdn.net/u012127882/article/details/46681651

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!