P1156 垃圾陷阱

斯德哥尔摩

2018-10-14 16:58:07

Personal

[P1156 垃圾陷阱](https://www.luogu.org/problemnew/show/P1156) 一眼看出是道背包题。 设$dp[i]$表示当堆到$i$高度时的生命是多少。 像背包一样,物品正着循环,高度倒着循环。 设枚举到第$i$个物品,当前枚举到的高度为$j$。 如果$dp[j]>=t_i$,分两种情况: 1. $j+h_i>=d$,就直接输出这个垃圾丢下来的时间,并结束程序。 2. $dp[j+h_i]=\max\{dp[j]\}$,即不吃这个垃圾,而用它来堆高度。 3. $dp[j]+=f_i$,即吃掉这个垃圾。 最后输出$dp[0]$,即出不去时,能存活的最长时间。 附代码: ```cpp #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define MAXN 110 using namespace std; int n,m,dp[MAXN]; struct Rubbish{ int t,f,h; friend bool operator <(const Rubbish &p,const Rubbish &q){ return p.t<q.t; } }a[MAXN]; inline int read(){ int date=0,w=1;char c=0; while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();} while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();} return date*w; } void work(){ dp[0]=10; for(int i=1;i<=n;i++) for(int j=m;j>=0;j--) if(dp[j]>=a[i].t){ if(j+a[i].h>=m){ printf("%d\n",a[i].t); return; } dp[j+a[i].h]=max(dp[j],dp[j+a[i].h]); dp[j]+=a[i].f; } printf("%d\n",dp[0]); } void init(){ m=read();n=read(); for(int i=1;i<=n;i++){a[i].t=read();a[i].f=read();a[i].h=read();} sort(a+1,a+n+1); memset(dp,-1,sizeof(dp)); } int main(){ init(); work(); return 0; } ```