ASSIGN - Assignments
Problem
Your task will be to calculate number of different assignments of n different topics to n students such that everybody gets exactly one topic he likes.
Input
First line of input contains number of test cases c (1<=c<=80). Each test case begins with number of students n (1<=n<=20). Each of the next n lines contains n integers describing preferences of one student. 1 at the ith position means that this student likes ith topic, 0 means that he definitely doesn't want to take it.
Output
For each test case output number of different assignments (it will fit in a signed 64-bit integer).
Example
Input: 3 3 1 1 1 1 1 1 1 1 1 11 1 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1 0 1 0 1 0 0 1 0 0 1 0 0 1 1 0 1 0 1 0 1 1 1 0 1 1 0 1 1 0 1 1 1 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 1 1 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 0 1 0 1 0 1 1 0 0 0 1 1 1 1 0 0 0 11 0 1 1 1 0 1 0 0 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 1 0 1 0 1 1 1 0 0 1 0 0 0 0 1 0 1 0 0 1 0 1 1 0 0 0 0 1 1 0 1 0 1 1 1 0 1 1 0 1 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 0 1 Output: 6 7588 7426
利用二进制表示集合,f[S][i]表示i个人形成S状态的座位的方案个数,答案就是 f[all][n], 注意爆int。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define inf 0x3f3f3f3f 4 long long f[2][(1<<20)+10]; 5 int e[21][21]; 6 int main() 7 { 8 int t,n,m,i,j,k; 9 cin>>t; 10 while(t--){ 11 cin>>n; 12 for(i=1;i<=n;++i) 13 for(j=1;j<=n;++j) cin>>e[i][j]; 14 memset(f,0,sizeof(f)); 15 f[0][0]=1; 16 int cur=0; 17 for(i=1;i<=n;++i){ 18 cur^=1; 19 memset(f[cur],0,sizeof(f[cur])); 20 for(j=0;j<(1<<n);++j){ 21 if(!f[cur^1][j]) continue; 22 for(k=1;k<=n;++k){ 23 if(e[i][k]&& ((1<<(k-1))&j)==0) { 24 f[cur][j|(1<<(k-1))]+=f[cur^1][j]; 25 } 26 } 27 } 28 /*for(j=0;j<(1<<n);++j){ 29 cout<<j<<' '<<f[cur][j]<<endl; 30 }*/ 31 } 32 cout<<f[cur][(1<<n)-1]<<endl; 33 } 34 return 0; 35 }