zoukankan      html  css  js  c++  java
  • bzoj3437: 小P的牧场

    题目链接

    bzoj3437: 小P的牧场

    题解

    dp转移有点玄学....好神的前缀和呀quq可能当时做时心态不太好 ?QAQ
    令$$sum[i]=sum_{k=1}^{i}b[k],cost[i]=sum_{k=1}^{i}{b[k]*k}$$
    得出dp方程

    [dp[i]=min_{k=0}^{i-1}{dp[k]+b[k]+(sum[i]-sum[k+1])*i-(cost[i]-cost[k+1])} ]

    然后就是斜率优化的套路了

    代码

    #include<cstdio>
    #include<cstring> 
    #include<algorithm> 
    inline int read() { 
        int x = 0,f = 1; 
        char c = getchar(); 
        while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} 
        while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
        return x * f; 
    }
    #define int long long 
    const int maxn = 1000007;
    int a[maxn],b[maxn],q[maxn]; 
    int n,dp[maxn]; 
    int sum[maxn],cost[maxn];
    //dp[i] = min{dp[j]+(sum[i]-sum[j])*i-(cost[i]-cost[j])} +a[i]
    double slop(int k,int j) {
        return double (dp[j] - dp[k] + cost[j] - cost[k]) / double (sum[j] - sum[k]);
    }
     
    main() {
        n = read(); 
        for(int i = 1;i <= n;++ i) a[i] = read(); 
        for(int i = 1;i <= n;++ i) b[i] = read(); 
        for(int i = 1;i <= n;++ i) sum[i] = sum[i - 1] + b[i], cost[i] = cost[i - 1] + b[i] * i;
        int l = 0,r = 0;
        for(int i = 1;i <= n;++ i) {
            while(l < r && slop(q[l],q[l + 1]) < i) l ++;
            int t = q[l];
            dp[i] = dp[t] + (sum[i] - sum[t]) * i - (cost[i] - cost[t]) + a[i];
            while(l < r && slop(i,q[r]) < slop(q[r],q[r - 1])) r --;
            q[++ r] = i;
        }
        printf("%lld
    ",dp[n]);
        return 0;
    }
    
    
  • 相关阅读:
    PHP 求多个数组的笛卡尔积,适用于求商品规格组合 【递归思想, 类似广度优先搜索】【原创】
    CCF推荐期刊会议
    SCI分区
    值和指针接收者的区别
    程序员练级攻略
    保险
    golang 有缓冲channel和无缓冲channel
    后台学习路线
    golang之反射
    atomic和mutex
  • 原文地址:https://www.cnblogs.com/sssy/p/8982158.html
Copyright © 2011-2022 走看看