HDU - 3182

15 篇文章 0 订阅
8 篇文章 1 订阅

一眼看上去有点像变形背包,但完全不是
每种汉堡只能选一种,选一种,且选i种汉堡 需要先作出规定的汉堡
比较难的就是如何判断这个状态是合法的,而对于确定的状态,答案是唯一的
合法表现在两方面:1.val>0 2.所有的汉堡满足依赖
这里的处理很优美:从一个合法状态到另一个合法状态,打标记

#include<iostream>
#include<stdio.h>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
const int INF=0x3f3f3f3f;
int v[20],w[20];
LL dp[(1<<16)]; //存放这种状态的最大收入
LL en[1<<16];//........剩下的eng
int vis[1<<16];
vector<int> sta[20];

bool judge(int state,int add) //能不能把add加到这个状态下
{
    for(auto v:sta[add]){
        if(!(state & (1<<(v-1)))) return 0;
    }
    return 1;
}
int main()
{
    int t;cin>>t;
    while(t--){
        int n,E;cin>>n>>E;
        for(int i=0;i<n;i++) cin>>v[i],sta[i].clear();
        for(int i=0;i<n;i++) cin>>w[i];
        for(int i=0;i<n;i++){
            int num;cin>>num;
            while(num--){
                int x;cin>>x;
                sta[i].pb(x);
            }
        }
        clr(dp,0);
        clr(vis,0);
        en[0] = E;
        vis[0]=1;
        LL ans=0;
        for(int i=0;i<(1<<n);i++){
            if(vis[i])
            for(int j=0;j<n;j++)
            if(!(i&(1<<j)) && judge(i,j)){
                if(en[i]-w[j] < 0) continue;
                int now=i|(1<<j);
                dp[now] = dp[i]+v[j];
                ans=max(ans,dp[now]);
                en[now] = en[i]-w[j];
                vis[now]=1;
            }
        }
        cout<<ans<<endl;

    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值