动态规划问题。方程有很多种。还是NOWCO上面的那个感觉好理解一些。
把每组游戏机提供的游戏,看成是一件物品,对每组内的物品进行01背包,也就是拿和不拿的决策。然后对于n组游戏机,每组游戏机和其提供的游戏组合看成是一件物品进行01背包,也是拿和不拿的决策。
这样就把这个问题给分解了,所有的DP完成了就能得到最优解。
我太弱了啊,,昨晚被这道题一直虐到笔记本没电,带着纠结和忐忑一直睡不着。。。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int dp_g[100002],dp_c[100002]; int maxd(int a,int b) { return a>b?a:b; } int main() { int n,v,i,j,k,wn[52],cn[52],ans; int w[52][12],p[52][12]; scanf("%d%d",&n,&v); for (i=1; i<=n; i++) { scanf("%d%d",wn+i,cn+i); for (j=1; j<=cn[i]; j++) { scanf("%d%d",&w[i][j],&p[i][j]); } } memset(dp_g,0,sizeof(dp_g)); memset(dp_c,0,sizeof(dp_c)); ans=0; for (i=1; i<=n; i++) { for (k=wn[i]; k<=v; k++) { dp_g[k]=dp_c[k-wn[i]]; } for (j=1; j<=cn[i]; j++) { for (k=v-w[i][j]; k>=wn[i]; k--) { dp_g[k+w[i][j]]=maxd(dp_g[k+w[i][j]],dp_g[k]+p[i][j]); } } for (k=wn[i]; k<=v; k++) { dp_c[k]=maxd(dp_g[k],dp_c[k]); } } printf("%d\n",dp_c[v]); }