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\n", dp[nr + 1]);
    return 0;
    }

转载于:https://www.cnblogs.com/Tony-Double-Sky/p/9879489.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值