题目大意:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6344
给出
n
n
n个答卷,每个答卷有
m
m
m道判断题,全部由
A
A
A和
B
B
B组成。这
m
m
m道判断题里有多少个题目子集,满足至少有
k
k
k对试卷在这些问题上面的答案是不同的。
思路:
m
≤
10
m\leq 10
m≤10,可以考虑先状压。
设
a
[
i
]
a[i]
a[i]为第
i
i
i张试卷压缩后的状态,那么枚举一个题目子集
S
S
S,将
S
S
S与所有试卷进行与运算,并记录进一个
h
h
h数组。如果现在枚举到第
j
j
j张试卷,
h
[
S
&
a
[
j
]
]
h[S\&a[j]]
h[S&a[j]]有
k
k
k个,那么就有
j
−
k
j-k
j−k张试卷可以和第
j
j
j张试卷匹配。最终判断匹配数,如果超过要求,这个子集就是可以的,
a
n
s
ans
ans加一。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#define N 1010
#define MAXN 1023
using namespace std;
int t,n,m,k,sum,ans,a[N],h[MAXN+10];
char c;
int main()
{
scanf("%d",&t);
for (int l=1;l<=t;l++)
{
scanf("%d%d%d",&n,&m,&k);
memset(a,0,sizeof(a));
for (int i=1;i<=n;i++)
for (int j=m-1;j>=0;j--)
{
cin>>c;
if (c=='A') a[i]+=(1<<j); //状压
}
ans=0;
for (int i=1;i<(1<<m);i++)
{
sum=0;
memset(h,0,sizeof(h));
for (int j=1;j<=n;j++)
{
h[i&a[j]]++; //记录个数
sum=sum+(j-h[i&a[j]]);
}
if (sum>=k) ans++;
}
printf("Case #%d: %d\n",l,ans);
}
}