比萨(Pizza)解题报告 - 暴力枚举加位运算加速

比萨(nhoi2009pj3)

Time Limit:1000MS  Memory Limit:65536K
Total Submit:3 Accepted:3

Description

NH的最大比萨店为即将来临的节日准备了 T 种不同加味的原料,但考虑到NH人的口味和其它一些因素,原料的使用有 N 种限制。
T种不同原料的编号为1..T。一个限制如“5 3”即表示5号和3号加味原料不能同时使用。如此,此时使用三种原料3,5,6的比萨是不允许的。
现在请你帮忙计算在上面条件下,最多可以制作多少不同的比萨(包括不添加任何加味原料的)。


Input

第一行:两个整数:T 和 N。
下面有N行:每行表示一种限制。每行的第一个整数 Z(1≦Z≦ T)表示这行后面有Z个表示原料编号的整数,这些原料不能同时出现在一个比萨中。


Output

只一行,一个整数表示在上面的限制下最多可以制成多少种不同比萨。

Sample Input


6 5
1 1
2 4 2
3 3 2 6
1 5
3 3 4 6


Sample Output
10

答案说明:
无加料;2;
2和3;2和6;
3;3和4;
3和6;4;
4和6;6。


Hint

1≦T≦20
1≦N≦52

反思:

这道题不难,一个两重循环就搞定了,依个枚举,再用位运算来判断。最主要要注意的是判断时位运算的优先级问题,尽量加一些括号,不然位运算的优先级问题很烦人……

#include <iostream>
#include <cstdio>
using namespace std;
int cantput[51];

void turn_to_two_base_and_print(int n){
string s;
while(n!=0){
s.push_back((char)(n&1)+'0');
n>>=1;
}
cout << s << endl;
}

int main(){
freopen("pizza.in","r",stdin);
freopen("pizza.out","w",stdout);
int n,t;
scanf("%d %d",&t,&n);
int z,tmp;
for (int i=0;i<n;++i){
scanf("%d",&z);
cantput[i]=0;
for (int j=0;j<z;++j){
scanf("%d",&tmp);
cantput[i]+=(1<<(tmp-1));
}
}
/*
for (int i=0;i<n;++i){
turn_to_two_base_and_print(cantput[i]);
}
*/

bool canUse;
unsigned int ans=0;
for (int i=0;i<(1<<(t));++i){
canUse=true;
for (int j=0;j<n;++j){
if ((i&cantput[j])==cantput[j]){
canUse=false;
break;
}
}
if (canUse){
++ans;
}
}
printf("%u\n",ans);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值