zoukankan      html  css  js  c++  java
  • [ZJOI2007]仓库建设

    这题,一道神奇的,斜率优化DP。。。柿子为什么辣么难写啊!!!!!!!!!!

    自己懒得手打了,引用一下别人的柿子。。。

    dp[i]=min(dp[i],dp[j]+c[i]+∑(x[i]-x[j])*p[j])

    s[i]=x[1]*p[1]+x[2]*p[2]+...+x[i]*p[i]

    a[i]=p[1]+p[2]+...+p[i]

    dp[i]=min(dp[i],dp[j]+c[i]-x[i]*(a[j]-a[i])-(s[i]-s[j]))

    然后经过一同化柿子。。。就出来了。。。QAQ。。。

    还要注意一点。。。这个柿子。。。最后化成斜率式的时候。。。

    要计算成double。。。否则会出现精度问题(luoguAC BZOJWA)

    呆码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 1000010
    #define ll long long
    using namespace std;
    
    ll f[N],s[N],a[N];
    ll q[N],c[N],p[N],x[N];
    int n;
    
    inline double doit(int i,int j)
    {
        return (f[j]+s[j]-f[i]-s[i])/(a[j]-a[i]);
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d%d",&x[i],&p[i],&c[i]);
        for(int i=1;i<=n;i++)
        {
            s[i]=s[i-1]+x[i]*p[i];
            a[i]=a[i-1]+p[i];
        }
        memset(f,50,sizeof(f)); f[0]=0;
        int head=0,tail=0;
        for(int i=1,j;i<=n;i++)
        {
            while(head<tail && x[i]>doit(q[head],q[head+1])) head++;
            j=q[head];
            f[i]=f[j]+c[i]-x[i]*(a[j]-a[i])-s[i]+s[j];
            while(head<tail && doit(q[tail],i)<doit(q[tail-1],q[tail])) tail--;
            q[++tail]=i;
        }
        printf("%lld",f[n]);
    }
    代码
  • 相关阅读:
    [转]测试的基本概念
    记录
    flash 与 程序通讯
    怎么正确的建立项目
    安装包的制作
    JS
    页面刷新定位
    [转]C#处理XML
    MSN机器人
    报表 的使用
  • 原文地址:https://www.cnblogs.com/zzzyc/p/9268085.html
Copyright © 2011-2022 走看看