• 【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
  • 相关阅读:
    利用console控制台调试php代码
    数据库比对脚本(PHP版)
    Symfony框架系列----1.入门安装
    Symfony框架系列----常用命令
    Symfony命令行
    Linux SCP指令
    Linux 搭建SVN服务器
    Linux下 保存 git账号密码
    js 视差滚动 记录备份
    移动端 -webkit-user-select:text; ios10 bug 解决方案
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6135179.html
Copyright © 2020-2023  润新知