luogu P1156 垃圾陷阱 背包问题
考虑Dp. 设f[i][j]表示当前在第i个垃圾,高度为j,最多可以存活到什么时候。 转移方程就是f[i][j]=max(f[i-1][j-h[i]], f[i-1][j]+a[i])
//第二维循环顺序,就是顺手写了个逆序,实际上没有影响,避免误导,已更正
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 struct dat 5 { 6 int t,a,h; 7 friend bool operator < (dat x,dat y) 8 { 9 return x.t < y.t; 10 } 11 } s[110]; 12 int m,n,ans; 13 int f[110][150]; 14 int main() 15 { 16 scanf("%d%d",&m,&n); 17 for(int i = 1;i <= n; i++) 18 scanf("%d%d%d",&s[i].t,&s[i].a,&s[i].h); 19 sort(s + 1,s + 1 + n); 20 f[0][0] = 10; 21 for(int i = 1;i <= n;i++) 22 { 23 for (int j = 0;j <= 130;j++) 24 { 25 if(j >= s[i].h && f[i - 1][j - s[i].h] >= s[i].t) 26 f[i][j] = max(f[i][j],f[i - 1][j - s[i].h]); 27 if(f[i - 1][j] >= s[i].t) 28 f[i][j] = max(f[i][j],f[i - 1][j] + s[i].a); 29 if(j >= m && f[i][j] >= s[i].t) 30 { 31 printf("%d\n",s[i].t); 32 return 0; 33 } 34 ans = max(ans,f[i][j]); 35 } 36 } 37 printf("%d\n",ans); 38 return 0; 39 40 }
f[i][j] 表示考虑前i个垃圾,存货j的最大高度,为-1时,表示状态非法。不推荐这个写法。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 using namespace std; 5 struct dat 6 { 7 int t,a,h; 8 friend bool operator < (dat x,dat y) 9 { 10 return x.t < y.t; 11 } 12 } s[110]; 13 int m,n,ans; 14 int f[110][3100]; 15 int main() 16 { 17 scanf("%d%d",&m,&n); 18 for(int i = 1;i <= n; i++) 19 scanf("%d%d%d",&s[i].t,&s[i].a,&s[i].h); 20 sort(s + 1,s + 1 + n); 21 memset(f,-1,sizeof(f)); 22 f[0][10] = 0; 23 for(int i = 1;i <= n;i++) 24 { 25 for (int j = 0;j <= 3000;j++) 26 { 27 //吃了当前垃圾 28 if (j >= s[i].a && j - s[i].a >= s[i].t && f[i - 1][j - s[i].a] >= 0) 29 f[i][j] = max(f[i][j],f[i - 1][j - s[i].a]); 30 //堆了当前垃圾 31 if (j >= s[i].t && f[i - 1][j] >= 0) 32 f[i][j] = max(f[i][j],f[i - 1][j] + s[i].h); 33 if (j >= s[i].t && f[i][j] >= m) 34 { 35 printf("%d\n",s[i].t); 36 return 0; 37 } 38 if (f[i][j] >= 0) 39 ans = max(ans,j); 40 } 41 } 42 printf("%d\n",ans); 43 return 0; 44 45 }
心之所动 且就随缘去吧