题解 洛谷P3859 【[TJOI2008]小偷】

题目传送门

这是一道有点变形的背包问题

这个小哥只能从0号门出,如果后面的门没关,但前面的门关了,他还是出不来。所以我们要把每个门的关闭时间更新为前面的门最早关闭时间(0不用)

d p i dp_i dpi记录第 i i i时刻后获得的宝石最大价值

上代码:

#include
#include
using namespace std;
int a[55],d[105],r[105],t[105],v[105],dp[1005];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;++i)
		scanf("%d",a+i);//每个门的关闭时间 
	for(int i=1;i<n;++i)
		a[i]=min(a[i],a[i-1]);//更新为前面门关闭最早时间(0号不用) 
	for(int i=1;i<=m;++i)
		scanf("%d%d%d",r+i,v+i,t+i);//如题意所示 
	for(int i=1;i<=m;++i)
		d[i]=a[r[i]];//第i个宝石的房间关闭时间 
	for(int i=1;i<a[0];++i)//枚举从第一时刻到第0号门关闭前一时刻
	{
		dp[i]=dp[i-1];//如果这一时刻什么都不拿 
		for(int j=1;j<=m;++j)
			if(i>=t[j]&&i<d[j])//这些时间够拿第j个宝石并且严格早于关闭时间 
				dp[i]=max(dp[i-t[j]]+v[j],dp[i]);//更新dp[i] 
	}
	printf("%d",dp[a[0]-1]);//输出最后一时刻(0号门关闭时间前一时刻)最大获得宝石价值 
	return 0;
 } 

你可能感兴趣的:(动态规划)