其他分享
首页 > 其他分享> > [USACO07NOV]Milking Time S 题解

[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