• bzoj1096: [ZJOI2007]仓库建设 斜率优化dp


    https://www.lydsy.com/JudgeOnline/problem.php?id=1096

    中文题意不说了,

    dp【i】表示从1到i所有产品都能放,而且第i个地方一定建仓库的最小费用,转移方程dp[i]=min(dp[j]+Σ(j<k<=i)x[i]-x[k])*p[k](1<=j<i)

    用sump表示p的前缀和,用sumpx表示p*x的前缀和,转移方程可变成dp[i]=dp[j]+x[i]*(sump[i]-sump[j])-(sumpx[i]-sumpx[j])

    dp[i] + x[i] * sump[j] = dp[j] + x[i] * sump[i] - (sumpx[i]-sumpx[j])

    b       +   k   *    x        =    y

    因为x【i】递增所以可以利用斜率优化,

    /**************************************************************
        Problem: 1096
        User: walfy
        Language: C++
        Result: Accepted
        Time:2528 ms
        Memory:55980 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double g=10.0,eps=1e-12;
    const int N=1000000+10,maxn=123456+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    ll xx[N],p[N],c[N],sumpx[N],sump[N],q[N],dp[N];
    inline ll x(int j)
    {
        return sump[j];
    }
    inline ll y(int j)
    {
        return dp[j]+sumpx[j];
    }
    inline double slope(int a,int b)
    {
        return (y(b)-y(a))/(x(b)-x(a));
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%lld%lld%lld",&xx[i],&p[i],&c[i]);
        for(int i=1;i<=n;i++)
        {
            sump[i]=sump[i-1]+p[i];
            sumpx[i]=sumpx[i-1]+p[i]*xx[i];
        }
        int head=1,last=1;q[last]=0;
        for(int i=1;i<=n;i++)
        {
            while(head<last&&slope(q[head],q[head+1])<xx[i])head++;
            int te=q[head];
            dp[i]=dp[te]+xx[i]*(sump[i]-sump[te])-sumpx[i]+sumpx[te]+c[i];
            while(head<last&&slope(q[last-1],q[last])>slope(q[last],i))last--;
            q[++last]=i;
    //        printf("%d %lld
    ",te,dp[i]);
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    /***********************
     
    ***********************/
    View Code

    (斜率优化的套路:有一项是关于x的函数乘上关于y的函数,然后关于x项的函数是单调的,其他项都是只包含一个(x或y)的函数)

  • 相关阅读:
    移动Oracle数据库表空间文件。
    Web页面嵌入复杂WinForm控件权限问题
    关于bleand2000下面oracle服务器优化
    祝大家新年快乐!
    CentOS安装配置MongoDB及PHP MongoDB 扩展安装配置 新风宇宙
    FastDFS介绍和配置过程 新风宇宙
    ubuntu下安装redisserver和phpredis 新风宇宙
    PHP安装fastDFS扩展 新风宇宙
    用socket发送流数据示用 php://input? 接受post数据(可实现php和c/c++数据通讯) 新风宇宙
    linux操作系统下c语言编程入门 新风宇宙
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8965038.html
Copyright © 2020-2023  润新知