Animals
蒟蒻

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;
}

  

posted @ 2018-11-05 13:58  年下丶  阅读(195)  评论(0编辑  收藏  举报
--- 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 百里守约 ---