[USACO07NOV]Milking Time S 题解
作者:互联网
题目描述
Bessie 可以在接下来 \(N\) 个小时内产奶,为了方便,我们把这 \(N\) 个小时 \(0\dots N-1\) 编号。
FJ 在这 \(N\) 个小时内有 \(M\) 段时间可以来给 Bessie 挤奶,第 \(i\) 段时间从 \(Start_i\) 开始到 \(End_i\) 结束,可以得到 \(Eff_i\) 加仑牛奶。
每次 FJ 给 Bessie 挤奶之后,Bessie 都要休息 \(R\) 个小时,FJ 才能开始下一次挤奶。
现在,FJ 需要您计算出 Bessie 在这 \(N\) 个小时内最多产多少奶。
输入格式
第一行有三个整数,分别表示 \(N,M,R\)。
第 \(2\dots M+1\) 行,第 \(i+1\) 行有三个整数 \(Start_i,End_i,Eff_i\),描述一段挤奶的时间。
输出格式
输出一行一个整数表示答案。
样例输入 #1
12 4 2
1 2 8
10 12 19
3 6 24
7 10 31
样例输出
43
数据规模与约定
对于全部的测试点,保证 \(1\le N\le 10^6\),\(1\le M\le 10^3\),\(1\le Start_i<end_i\le N\),\(1\le Eff_i\le 10^6\)。
题目不难,解法妙在一个邻接表的使用。
设 \(dp[i]\) 表示到时间 \(i\) 时可以获得的最大牛奶量。
所以存在 \(dp[i]=dp[i-1]\) 。
当前时间若是一头奶牛结束挤奶的时间,便有\(dp[i]=max(dp[i],dp[e[j].start-r]+w[j])\) 。
使用邻接表 \(h\) 访问的特殊性质,可以有效减轻工作量。
Code.
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m,r,w[N],dp[N],h[N],ne[N],e[N],idx;
void add(int u,int v,int c) {ne[++idx]=h[u],e[idx]=v,w[idx]=c,h[u]=idx;}
int main()
{
memset(h,-1,sizeof h);
scanf("%d%d%d",&n,&m,&r);
for(int i=1;i<=m;i++)
{
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
add(v,u,c);
}
for(int i=1;i<=n;i++)
{
dp[i]=dp[i-1];
for(int j=h[i];~j;j=ne[j])
dp[i]=max(dp[i],dp[max(0,e[j]-r)]+w[j]);
}
printf("%d",dp[n]);
return 0;
}
标签:10,le,idx,int,题解,Time,Milking,Bessie,dp 来源: https://www.cnblogs.com/EastPorridge/p/16365019.html