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;
}