zoukankan      html  css  js  c++  java
  • P2120 [ZJOI2007]仓库建设(dp+斜率优化)

    思路

    首先暴力DP显然,可以得20分

    加上一个前缀和优化,可以得到40分

    然后上斜率优化

    (sum_i)(sum_{1}^iP_i)(sump_i)(sum_{1}^{i}P_i imes Pos_i)

    则决策j优于决策i的条件可以表示为

    [dp_j+C_t+pos_t imes(sum_t-sum_{j}) - (sump_t - sump_{j})<dp_i+C_t+pos_t imes(sum_t-sum_{i}) - (sump_t - sump_{i}) ]

    化简即可

    这里贴上我认为写的不错的一篇题解其实是懒得写式子了

    dummy的题解

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define int long long
    using namespace std;
    int dp[1000010],n,c[1000010],p[1000010],pos[1000010],sum[1000010],summ[1000010];
    int queue[1000010],h,t;
    int T(int x){
        return dp[x]+summ[x];
    }
    int S(int x){
        return sum[x];
    }
    signed main(){
        // freopen("6.in","r",stdin);
        memset(dp,0x3f,sizeof(dp));
        scanf("%lld",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld %lld %lld",&pos[i],&p[i],&c[i]);
            sum[i]=sum[i-1]+p[i];
            summ[i]=summ[i-1]+p[i]*pos[i];
        }
        dp[0]=0;
        // dp[1]=c[1];
        for(int i=1;i<=n;i++){
            while(h<t&&1.0*(T(queue[h+1])-T(queue[h]))/((S(queue[h+1])-S(queue[h])))<pos[i])
                h++;
            dp[i]=dp[queue[h]]+pos[i]*(sum[i]-sum[queue[h]])-(summ[i]-summ[queue[h]])+c[i];
            while(h<t&&1.0*(T(i)-T(queue[t]))/((S(i)-S(queue[t])))<1.0*(T(queue[t-1])-T(queue[t]))/((S(queue[t-1])-S(queue[t]))))
                t--;
            queue[++t]=i;
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    
  • 相关阅读:
    动态规划
    Python第二天学习
    Python第一天学习---基础语法
    java易错知识点
    C语言---指针复习
    排序汇总
    课程设计---创建族谱管理系统
    Vue第五篇 Vue的生命周期
    Vue第四篇 Vue路由系统
    Vue第三篇 Vue组件
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10129500.html
Copyright © 2011-2022 走看看