 /**//*
题意:n种材料,m种方案,每种方案会选择一些物品做出产品,问最多能
做出多少种产品,但材料只能使用一次

比较特别的01背包
看二进制位,就是背包容量了 , 方案会占据一些位(或者说容量)
用01背包更新即可
这里二进制枚举补集的子集

不是很快 600ms
方案很多重复、包含
可以先去重,还有去掉一些包含的,然后会快很多 , 200多ms吧
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstdlib>
#include<iostream>

using namespace std;

const int INF = 1000000000;
const int MAXN = 10010;

int dp[1<<16];

int main()
  {

#ifdef ONLINE_JUDGE
#else
freopen("in", "r", stdin);
#endif

int n , m;
while( ~scanf("%d%d",&n,&m) )
 {
int limit = (1<<n);
fill(dp,dp+limit,0);
for(int i = 0 ; i < m ; i++)
 {
scanf("%d",&n);
if(n==0)continue;//
int mask = 0 , x;
for(int j = 0 ; j < n ; j++)
 {
scanf("%d",&x);
mask |= (1<<x-1);
}
dp[mask] = max(dp[mask] , 1);
int _mask = mask ^ (limit-1);//补集
for(int j = _mask ; j ; j = (j-1) & _mask)
 {
dp[mask | j] = max(dp[mask | j] , dp[j] + 1);
}
}
printf("%d\n" , *max_element(dp,dp+limit) );
}
return 0;
}


|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|