洛谷P1446 [HNOI2008]Cards

置换群+dp

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 #include<cmath>
 7 #define MAXN 65
 8 #define ll long long
 9 #define pb push_back
10 #define ft first
11 #define sc second
12 #define mp make_pair
13 using namespace std;
14 int Inv(int a,int p){
15     int b=p-2;
16     int ret=1;
17     while(b){
18         if(b&1){
19             ret=1LL*ret*a%p;
20         }    
21         a=1LL*a*a%p;
22         b>>=1;
23     }
24     return ret;
25 }
26 int sr,sb,sg,n,m,MOD;
27 int a[MAXN][MAXN];
28 int f[25][25][25];
29 int b[MAXN],d[MAXN];
30 int calc(int x){
31     memset(b,0,sizeof(b));
32     memset(d,0,sizeof(d));
33     int cnt=0;
34     for(int i=1;i<=n;i++){
35         if(!b[i]){
36             cnt++;
37             for(int j=i;!b[j];j=a[x][j]){
38                 d[cnt]++;
39                 b[j]=1;
40             }
41         }
42     }
43     memset(f,0,sizeof(f));
44     f[0][0][0]=1;
45     for(int h=1;h<=cnt;h++){
46         for(int i=sr;i>=0;i--){
47             for(int j=sb;j>=0;j--){
48                 for(int k=sg;k>=0;k--){
49                     if(i>=d[h])(f[i][j][k]+=f[i-d[h]][j][k])%=MOD;
50                     if(j>=d[h])(f[i][j][k]+=f[i][j-d[h]][k])%=MOD;
51                     if(k>=d[h])(f[i][j][k]+=f[i][j][k-d[h]])%=MOD;
52                 }
53             }
54         }    
55     }
56     return f[sr][sb][sg];
57 }
58 int main()
59 {
60 //    freopen("data.in","r",stdin);
61     scanf("%d%d%d%d%d",&sr,&sb,&sg,&m,&MOD);
62     n=sr+sb+sg;
63     int t;
64     for(int i=1;i<=m;i++){
65         for(int j=1;j<=n;j++){
66             scanf("%d",&t);
67             a[i][t]=j;
68         }
69     }
70     m++;
71     for(int i=1;i<=n;i++)a[m][i]=i;
72     int ans=0;
73     for(int i=1;i<=m;i++){
74         ans+=calc(i);
75         ans%=MOD;
76     }
77     ans=1LL*ans*Inv(m,MOD)%MOD;
78     printf("%d\n",ans);
79     return 0;
80 }

 

posted @ 2018-01-21 17:09  white_hat_hacker  阅读(132)  评论(0编辑  收藏  举报