zoukankan      html  css  js  c++  java
  • 【BZOJ 1010】[HNOI2008]玩具装箱toy

    【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1010

    【题意】

    【题解】

    dp[i] = min(dp[i],dp[j]+sqr(sum[i]-sum[j]+i-(j+1)-l));
    dp[i] = min(dp[i],dp[j]+sqr((sum[i]+i)-(sum[j]+j)-(l+1)));
    令f[i] = sum[i] + i;
    令c=l+1;
    dp[i] = min(dp[i],dp[j]+sqr(f[i]-f[j]-c));
    当j< k< i时;
    假设
    dp[j]+sqr(f[i]-f[j]-c)>dp[k]+sqr(f[i]-f[k]-c) ······①
    设i之后的状态t;
    f[t]=f[i]+v;
    想知道i对后面的t的状态的影响;
    dp[j]+sqr(f[t]-f[j]-c)>dp[k]+sqr(f[t]-f[k]-c);
    dp[j]+sqr(f[i]+v-f[j]-c)>dp[k]+sqr(f[i]+v-f[k]-c);
    dp[j]+sqr(f[i]-f[j]-c)+sqr(v)+2*(f[i]-f[j]-c)v>dp[k]+sqr(f[i]-f[k]-c)+sqr(v)+2(f[i]-f[k]-c)*v;
    f[i]-f[j]-c>f[i]-f[k]-c
    ->
    f[k]>f[j];
    而f[k]>f[j]显然成立(k>j,且f单调递增);
    所以,当j< k< i,①式成立的时候
    只要考虑决策点k就好;j不会对后面的答案造成影响;不用考虑它;
    然后看看①式成立的条件是什么;
    ->将①式展开;
    dp[j]+sqr(f[i]-f[j]-c)>dp[k]+sqr(f[i]-f[k]-c)
    dp[j]+sqr(f[i])+sqr(f[j]+c)-2*f[i](f[j]+c)>dp[k]+sqr(f[i]+sqr(f[k]+c)-2*f[i](f[k]+c);
    dp[j]+sqr(f[j]+c)-2*f[i](f[j]+c)>dp[k]+sqr(f[k]+c)-2*f[i](f[k]+c);
    dp[j]-dp[k]+sqr(f[j]+c)-sqr(f[k]+c)>2*f[i](f[j]+c)-2*f[i](f[k]+c);
    (dp[j]-dp[k]+sqr(f[j]+c)-sqr(f[k]+c))>2*fi
    f[j]>f[k]要改变不等式方向
    (dp[j]-dp[k]+sqr(f[j]+c)-sqr(f[k]+c))/(2*(f[j]-f[k]))< f[i] ····②
    也就是说,如果②式成立的话;
    就k的决策更好,否则的话j的决策更好;
    且根据上面的分析可知,这时候的决策对后面的结果不会有“坏”的影响;
    (也就是当前的决策时可以推出后面的答案的);
    写个单调队列就好;


    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 5e4+100;
    
    LL n,l,C;
    LL c[N],f[N],sum[N],dp[N];
    int dl[N],h,t;
    
    LL sqr(LL x) { return x*x;}
    
    double ju(int j,int k)
    {
        double t = (dp[j]-dp[k]+sqr(f[j]+C)-sqr(f[k]+C))/(2*(f[j]-f[k]));
        return t;
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rel(n),rel(l);C = l+1;
        rep1(i,1,n)
        {
            rel(c[i]);
            sum[i] = sum[i-1]+c[i];
            f[i] = sum[i]+i;
        }
        h = 1,t = 1;
        dl[1] = 0,dp[0] = 0;
        rep1(i,1,n)
        {
            while (h<t && ju(dl[h],dl[h+1])<=f[i]) h++;
            int temp = dl[h];
            dp[i] = dp[temp] + sqr(f[i]-f[temp]-C);
            while (h<t && ju(dl[t-1],dl[t])>ju(dl[t],i)) t--;
            t++;
            dl[t] = i;
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
  • 相关阅读:
    IO模型详解
    Java中的CAS实现原理
    深入理解幂等性
    区块链基本原理入门
    通俗易懂讲解IO模型
    java高级特性(4)--枚举
    static、final和finalize详解
    锁(3)-- DB锁
    浅析项目中的并发
    分布式(1)-- 分布式锁
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626610.html
Copyright © 2011-2022 走看看