每个汉堡有价值a,和消耗b,并且做有些汉堡之前要先做好其他汉堡,求最大能得到的价值
N《=15 状压DP
#include "stdio.h"
#include "string.h"
#include "math.h"
struct comp
{
int x,y;
}dp[16][1<<16];
int main()
{
int Case,n,m,i,j,t,k,x,Max;
int a[16],b[16],dis[16],mark[16];
scanf("%d",&Case);
while (Case--)
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
scanf("%d",&b[i]);
for (i=1;i<=n;i++)
{
scanf("%d",&k);
dis[i]=0;
while (k--)
{
scanf("%d",&x);
dis[i]+=pow(2,x-1);
}
}
t=1<<n;
for (i=1;i<=n;i++)
mark[i]=pow(2,i-1);
for (i=0;i<=n;i++)
for (j=0;j<t;j++)
{
dp[i][j].x=-1;
dp[i][j].y=0;
}
dp[0][0].x=0;
Max=0;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
for (k=0;k<t;k++)
if ( (dis[j]&k)==dis[j] && (mark[j]&k)==0 && dp[i-1][k].x!=-1 &&dp[i-1][k].y+b[j]<=m)
{
if (dp[i][k].x<dp[i-1][k].x+a[j])
{
dp[i][k+mark[j]].x=dp[i-1][k].x+a[j];
dp[i][k+mark[j]].y=dp[i-1][k].y+b[j];
if (dp[i][k+mark[j]].x>Max) Max=dp[i][k+mark[j]].x;
}
}
printf("%d\n",Max);
}
}