动态规划问题。方程有很多种。还是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]);
}