• P2889 [USACO07NOV]挤奶的时间Milking Time


    P2889 [USACO07NOV]挤奶的时间Milking Time

    奶牛Bessie在0~N时间段产奶。农夫约翰有M个时间段可以挤奶,时间段f,t内Bessie能挤到的牛奶量e。奶牛产奶后需要休息R小时才能继续下一次产奶,求Bessie最大的挤奶量。


    错误日志: dp[i]转移的设计强制选择了第 i 个(自己还没发现)【然后后面发现又有问题唉】


    Solution

    先把 (R) 累积到右端点中, 排序
    (dp[i]) 为考虑前 (i) 个区间, 第 (i) 个区间必选的最大获利
    为什么要必选呢? 这样才能方便转移
    容易写出方程:$$dp[i] = v[i] + max_{0 leq j leq i - 1}dp[j] [r_{j} leq l_{i}]$$
    再回到为什么要必选, 这样才能有转移的判断条件(从必选的转移而来)
    为了方便, 我们引入一个起点, 一个重点, 权值都为 (0) ,不影响结果而可以方便计算

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define LL long long
    #define REP(i, x, y) for(int i = (x);i <= (y);i++)
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 2019;
    int num, nr, R;
    struct Node{int l, r, v;}I[maxn];
    bool cmp(Node a, Node b){return a.l < b.l;}
    int dp[maxn];
    int main(){
    	num = RD(), nr = RD(), R = RD();
    	REP(i, 1, nr)I[i] = (Node){RD(), RD() + R, RD()};
    	sort(I + 1, I + 1 + nr, cmp);
    	I[0].r = -1026;//起点
    	I[nr + 1].l = num + R + 19;//终点
    	REP(i, 1, nr + 1){
    		REP(j, 0, i - 1){
    			if(I[j].r <= I[i].l)dp[i] = max(dp[i], dp[j] + I[i].v);
    			else dp[i] = max(dp[i], dp[j] - I[j].v + I[i].v);
    			}
    		}
    	printf("%d
    ", dp[nr + 1]);
    	return 0;
    	}
    
  • 相关阅读:
    Leetcode 290 Word Pattern
    Leetcode 205 Isomorphic Strings
    Leetcode 345 Reverse Vowels in a String
    Leetcode 151 Reverse Words in a String
    Leetcode 344 Reverse String
    Leetcode 383 Ransom Note
    leetcode 387 First Unique Character in a String
    反码补码和位运算
    SpringBoot进阶
    布隆过滤器
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9879489.html
Copyright © 2020-2023  润新知