• 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;
    }
    
  • 相关阅读:
    VC++下封装ADO类以及使用方法
    MFC浅析(7) CWnd类虚函数的调用时机、缺省实现
    JavaScript原生数组函数
    C#4.0泛型的协变,逆变深入剖析
    《这就是搜索引擎:核心技术详解》总结
    栈和队列
    JS菜单条智能定位效果
    实现模型工厂,依赖注入以及格式配置
    Intellij IDEA 快捷键整理
    printf code
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10129500.html
Copyright © 2020-2023  润新知