HDU 3182 状态压缩dp

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值