#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
using namespace std;
int val[20],cost[20];
int dp[1<<16],money[1<<16],limit[20][20];
//dp[i]是当前状态的最大价值,money[i]当前的剩余能量
bool judge(int idx,int now){ //物品号,状态
for(int i=1;i<=limit[idx][0];i++){
if(! (now & (1<<(limit[idx][i]-1))) ) return 0;
//如果当前状态下,需要做的汉堡还没做好,则不满足约束条件
}
return true;
}
int main(){
int t;
int n,m;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",val+i); //每个汉堡的价值
for(int i=1;i<=n;i++)
scanf("%d",cost+i); //每个汉堡耗费的能量
for(int i=1;i<=n;i++){
scanf("%d",&limit[i][0]); //读入汉堡间的依赖关系
for(int j=1;j<=limit[i][0];j++)
scanf("%d",&limit[i][j]);
}
for(int i=0;i<(1<<n);i++){
dp[i] = INT_MIN;
money[i] = 0;
}
dp[0] = 0;
money[0] = m;
int res = 0;
for(int i=0;i<(1<<n);i++){ //枚举所有状态
for(int j=1;j<=n;j++){ //枚举所有物品
if(i & (1<<(j-1))) continue; //若当前状态已经制作了该汉堡,则继续
int now = i||(1<<(j-1)); //加入该物品
if(dp[now]<dp[i]+val[j] && money[i]>=cost[j] && judge(j,i)){
//价值更大 且满足约束条件 并且当前的能量够用
dp[now] = dp[i]+val[j];
res = max(dp[now],res);
money[now] = money[i]-val[j];
}
}
}
printf("%d\n",res);
}
return 0;
}
HDU 3182 状态压缩dp
最新推荐文章于 2019-12-18 20:07:00 发布