Day5-T3
原题目
要开运动会了,神犇学校的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; }