Luo Gu P1446 / BZOJ1004 Cards Burnside lemma +01 backpack

The meaning of problems: n-cards, there are R + G + B = 3 and the number n of colors, with the three colors required to dye n cards. n m is shuffled cards have manner, asked the same number of essentially different ways shuffling staining protocol.

Solution: This question is very interesting, problem solution reference Hzwer seniors. I'll summarize it here:

See essentially the same stain program we can easily think of Burnside lemma and Polya theorem, but this problem can not Polya Theorem, and why? Because the number of Ployd color staining is generally not limited, so when the loop section is color l c, when c ^ l is the mode number (one cycle is because the same program to have the same color so dyed). However, this problem limits the number of colors, each grid has not directly c choices can not be used Polyd theorem.

So, now we have to ensure the same color but not Ployd within a cycle it? We use of Burnside: imagine such a way, we must have R red, G green, B blue, and each loop section we can choose it dyed R / G / B. It is not that a 01 backpack models, each loop section is an item, RGB is capacity constraints, then we can use the number to 01 backpack computing solutions.

For details, see the code and comments.

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=25;
int n,r,g,b,m,P,a[65],d[65];

void exgcd(int a,int b,int& d,int& x,int& y) { //ax+by=gcd(a,b) 
    if (!b) { d=a;x=1;y=0; } 
    else { exgcd(b,a%b,d,y,x); y-=x*(a/b); }
}

bool Show [ 65 ];
DP LL [ 65 ] [N] [N] [N];   // DP [l] [i] [J] [K] l cycles before the representative section composed of an i-th one Rj program number Gk B- 
LL solve ( ) {   // the number of programs calculated each time a permutation groups (corresponding to 01 to make a backpack) 
    for ( int I = . 1 ; I <= n-; I ++) VIS [I] = 0 ;
     int NUM = 0 , = now . 1 ;
     for ( int I = . 1 ; I <= n-; I ++) {   // count the loops section 
        IF (VIS [I]) Continue ;
        D [ ++ NUM] = . 1 ; now = I;   // number of cycles section / size 
        VIS [now] = . 1 ;
         the while (! {VIS [A [now]])
            d [whether] ++ ;
            vis[a[now]]=1;
            now=a[now];
        }
    }
    for (int l=0;l<=num;l++) for (int i=0;i<=r;i++) for (int j=0;j<=g;j++) for (int k=0;k<=b;k++) 
        dp[l][i][j][k]=0;
    DP [ 0 ] [ 0 ] [ 0 ] [ 0 ] = . 1 ;   // initialization 
    for ( int L = . 1 ; L <= NUM; L ++)   // number of cycles of the number corresponding to the article section 
        for ( int I = 0 ; I <= R & lt; I ++ )
             for ( int J = 0 ; J <= G; J ++ )
                 for ( int K = 0 ; K <= B; K ++ ) {
                     IF (I> = D [L]) DP [L ] [I] [J] [K] = (DP [L] [I] [J] [K] + DP [L- . 1 ] [ID [L]] [J] [K])%P;
                    if (j>=d[l]) dp[l][i][j][k]=(dp[l][i][j][k]+dp[l-1][i][j-d[l]][k])%P;
                    if (k>=d[l]) dp[l][i][j][k]=(dp[l][i][j][k]+dp[l-1][i][j][k-d[l]])%P;
                }
    return dp[num][r][g][b];            
}

int main ()
{
    scanf("%d%d%d%d%d",&r,&g,&b,&m,&P);
    n=r+g+b;
    LL ans=0;
    for (int i=1;i<=m;i++) {
        for (int j=1;j<=n;j++) scanf("%d",&a[j]);
        ANS + = Solve ();   // accumulated number of all permutations 
    }
     for ( int I = . 1 ; I <= n-; I ++) A [I] = I;
    ans+=solve();
    int x,y,d; exgcd(m+1,P,d,x,y); 
    X = (X P + P%)% P;   // determined modulo m + 1 P Inverse membered 
    COUT ANS * X% P << << endl;
     return  0 ;
}

 

Guess you like

Origin www.cnblogs.com/clno1/p/11604600.html