原题目
要开运动会了,神犇学校的n个班级要选班服,班服共有100种样式,编号1~100。现在每个班都挑出了一些样式待选,每个班最多有100个待选的样式。要求每个班最终选定一种样式作为班服,且该班的样式不能与其他班级的相同,求所有可能方案的总数,由于方案总数可能很大,所以要求输出mod 1000000007后的答案。
共有T组数据.
对于每组数据,第一行为一个整数n,表示有n个班级。
2~n+1行,每行有最多100个数字,表示第i-1班待选班服的编号。
对于每组数据,输出方案总数 mod 1000000007后的答案。
S1:
Input:
2 3 5 100 1 2 5 100 2 3 5 8 100
Output:
4 4
Describe:状压啊~ f[i][j]+=f[i-1][j^(1<<k)],f[i][j]%=mod
code:
#include<bits/stdc++.h>
#define mod 1000000007
#define maxn 100
using namespace std;
bool flg;
int a[maxn+5],t,n,f[maxn+5][(1<<10)+10],x;
inline int read(){
int ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
flg=ch=='\n';return ret*f;
}
inline void write(int x){
if(x<0){putchar('-');write(-x);return;}
if(x/10) write(x/10);
putchar(x%10+'0');
}
int main() {
cin>>t;
while(t--){
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
n=read(),f[0][0]=1;
for(int i=1;i<=n;i++){
flg=0;
while(!flg){
x=read();
a[x]+=1<<(i-1);
}
}
for(int i=1;i<=maxn;i++){
for(int j=0;j<(1<<n);j++){
for(int k=0;k<n;k++) //for(int k=0;k<=n;k++)
if((a[i]>>k&1)&&(j>>k&1)) //if((a[i]>>k)&&(j>>k))
f[i][j]+=f[i-1][j^(1<<k)],f[i][j]%=mod;
f[i][j]+=f[i-1][j];f[i][j]%=mod;
}
}
write(f[maxn][(1<<n)-1]);puts("");
}
return 0;
}