P2889 [USACO07NOV]Milking Time S
题目大意:第 \(i\) 段时间从 \(X\) 开始到 \(Y\) 结束,可以得到 \(\rm cofe\) 个牛奶。每次
FJ
给Bessie
挤奶之后,Bessie
都要休息 \(R\) 个小时,FJ
才能开始下一次挤奶。求最大的牛奶量
易得要按右端点排序,这样才能最大。
定义 \(dp_i\) 表示前 \(i\) 个时间段最大的牛奶量,其中第 \(i\) 次要挤奶。
考虑前面的时间段 \(j\) ,如果 a[i].l-a[j].r<=R
就符合条件,则 \(dp_i=\max (dp_j+a[i].ti)\) 。
我们会发现都有相同的 \(a[i].ti\) ,那么可以先 \(dp_i+=a[i].ti\),每次循环 \(dp_i=max(dp_j)\)。
初始化 \(dp_1=a[1].ti\),然后就是开心的程序了!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,R;
struct stu{
int l,r;
int ti;
}ed[1005];
bool cmp(stu x,stu y){
return x.r<y.r;
}
int dp[1005];//dp[i]表示以i结尾前i个时间段最大
int main(){
cin>>n>>m>>R;
for(int i=1;i<=m;i++){
cin>>ed[i].l>>ed[i].r>>ed[i].ti;
}
sort(ed+1,ed+m+1,cmp);
dp[1]=ed[1].ti;
for(int i=2;i<=m;i++){
for(int j=1;j<i;j++){
if(ed[i].l-ed[j].r>=R){
dp[i]=max(dp[i],dp[j]);
}
}
dp[i]+=ed[i].ti;
}
int maxn=-100;
for(int i=1;i<=m;i++){
maxn=max(maxn,dp[i]);
}
cout<<maxn<<endl;
}
/*
1 2 8
10 12 19
3 6 24
7 10 31
*/
/*
1 2 8
3 6 24
7 10 31
10 12 19
*/