Luogu P1156垃圾陷阱

Description:

卡门已经落了到“垃圾井”中。它的深度为D(2≤D≤100)英尺。
卡门想把垃圾堆起来,等到堆得与井同样高时,她就能逃出井外了。另外,卡门可以通过吃一些垃圾来维持自己的生命。
每个垃圾都可以用来吃或堆放,并且堆放垃圾不用花费卡门的时间。
假设卡门预先知道了每个垃圾扔下的时间t(0<t≤1000),以及每个垃圾堆放的高度(1≤h≤25)和吃进该垃圾能维持生命的时间f(1≤f≤30),要求出卡门最早能逃出井外的时间,假设卡门当前体内有足够持续10小时的能量,如果卡门10小时内没有进食,卡门就将饿死。

Analysis:

f[i][j] := 前 i 個垃圾在高度爲 j 時能存活的時間(是一段時間,而不是存活到什麼時候)
有點像 01 背包 第i個垃圾可以選擇吃或者增加高度,如果吃,f[i][j] 由 f[i-1][j] + e[i] 轉移而來,如果不吃,f[i][j] 由 f[i-1][j - h[i]] 轉移。
邊界 f[0][0] = 10,j 從 0 開始枚舉!!!

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define _rqy rqynb
#define t(i) g[i].t
#define h(i) g[i].h
#define e(i) g[i].e
using namespace std;
const int N = 110;
struct trash{
	int t,e,h;

	bool operator < (const trash &p) const {
		return t < p.t;
	} 
}g[N];
int f[N][N],n,d;
int main()
{
	scanf("%d%d",&d,&n);
	for(int i = 1;i <= n;++i)
	{
		scanf("%d%d%d",&g[i].t,&g[i].e,&g[i].h);
	}
	sort(g+1,g+1+n);
	memset(f,-1,sizeof(f));
	f[0][0] =10;
	for(int i = 1;i <= n;++i)
	{
		for(int j = 0;j <= d;++j)
		{
			if(f[i-1][j] >= (t(i) - t(i-1)))
				f[i][j] = f[i-1][j] - (t(i) - t(i-1))+ e(i);
			//!
			if(j >= h(i) && f[i-1][j - h(i)] >= t(i) - t(i-1))
				f[i][j] = max(f[i][j],f[i-1][j - h(i)] - (t(i) - t(i-1)));
			
			if(j >= d && f[i][j] >= 0)
			{
				printf("%d
",t(i));
				return 0;
			}
		}
	}
	int ans = 10;
	for(int i = 1;i <= n;++i)
	{
		if(ans < t(i)) break;
		ans += e(i);
	}
	printf("%d
",ans);
	return 0;
}
岂能尽如人意,但求无愧我心
原文地址:https://www.cnblogs.com/Zforw/p/11385177.html