zoukankan      html  css  js  c++  java
  • 【BZOJ】1096 [ZJOI2007]仓库建设

    【算法】DP+斜率优化

    【题解】状态转移方程:f[i]=min(f[j]+g(i+1,j-1))+c[i]

    关键在于如何O(1)计算g(i+1,j-1)。

    推导过程:http://blog.csdn.net/PoPoQQQ/article/details/40504949

    当d(j,k)中j<k且k更优时,得到斜率不等式:

    (f[j]-f[k]+sumpx[j]-sumpx[k])/(sump[j]-sump[k])<x[i]

    于是斜率优化。

    斜率优化:http://www.cnblogs.com/onioncyc/p/6113450.html

    【细节】

    1.是while不是if。。。

    2.p[i]*x[i]*1ll。。。

    3.转double运算优先度高于除法的样子。

    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=1000010;
    int q[maxn],x[maxn],p[maxn],c[maxn],n;
    ll f[maxn],sump[maxn],sumpx[maxn];
    double calc(int j,int k)
    {return (double)(f[j]-f[k]+sumpx[j]-sumpx[k])/(sump[j]-sump[k]);}//important3
    ll g(int i,int j)
    {return x[i]*(sump[i-1]-sump[j])-(sumpx[i-1]-sumpx[j]);}
    int main()
    {
        scanf("%d",&n);
        sump[0]=sumpx[0]=0;
        for(int i=1;i<=n;i++)
         {
             scanf("%d%d%d",&x[i],&p[i],&c[i]);
             sump[i]=sump[i-1]+p[i];
             sumpx[i]=sumpx[i-1]+1ll*p[i]*x[i];//important2
         }
        int head=1,tail=1;q[1]=0;f[0]=0;
        for(int i=1;i<=n;i++)
         {
             while(head<tail&&calc(q[head],q[head+1])<x[i])head++;
             f[i]=f[q[head]]+g(i,q[head])+c[i];
             while(head<tail&&calc(q[tail-1],q[tail])>calc(q[tail],i))tail--;//important1
             q[++tail]=i;
         }
        printf("%lld",f[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    第九周PSP
    c++的继承方式
    matlab的应用
    beta发布的评论
    本周psp
    历年作品点评
    JSON解析数据
    每周工作量及代码统计(第七周)
    词频统计(WEB)版
    评论alpha发布
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6135179.html
Copyright © 2011-2022 走看看