首页 > 代码库 > 状态压缩 HDU 3182

状态压缩 HDU 3182

t组数据

n个汉堡 e的能量

接下来的2行

val    n个 得到的权

cost  n个 花去的能量

接下来n行

每行一个q  q个数字

代表这类汉堡做好要的前提  每个汉堡只能用一次

#include<stdio.h>
#include<algorithm>
#include<string.h>

using namespace std;

#define MAXN 1<<15
int dp[MAXN];
int val[101],co[101];
int x[101];
int cost[MAXN];
int n,e;
  
void Init()  //预处理出所有状态要的能量
{
    int en=(1<<n);
    for(int i=0;i<en;i++)
    {
        for(int j=0;j<n;j++)
        {
            if((i&(1<<j)))
                cost[i]+=co[j];
        }
    }
}
bool jud(int state,int p)  //判断这个状态是否合法
{
    if((state&x[p])==x[p]&&cost[state]+co[p]<=e)
        return 1;
    return 0;
}
int main()
{
    int t;
    scanf("%d",&t);

    while(t--)
    {

        scanf("%d%d",&n,&e);
        memset(dp,-1,sizeof(dp));
        memset(cost,0,sizeof(cost));
        memset(x,0,sizeof(x));

        for(int i=0;i<n;i++)
            scanf("%d",&val[i]);
        for(int i=0;i<n;i++)
            scanf("%d",&co[i]);
        for(int i=0;i<n;i++)
        {
            int a;
            scanf("%d",&a);
            for(int j=1;j<=a;j++)
            {
                int b;
                scanf("%d",&b);
                b--;
                x[i]|=(1<<b);
            }
        }
        Init();
        int ans=0;
        dp[0]=0;
        int en=(1<<n);
        for(int i=0;i<en;i++)
        {
            if(dp[i]!=-1)
                for(int j=0;j<n;j++)
                {
                    if(jud(i,j)&&(i&(1<<j))==0) /这个汉堡可以做
                    {
                        dp[i|(1<<j)]=dp[i]+val[j]; //前面的权值+这个的权
                        ans=max(ans,dp[i|(1<<j)]);
                    }
                }
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

状态压缩 HDU 3182