羅区P1446 / BZOJ1004カードバーンサイドの補題01リュックサック

問題の意味:N-カードは、R + G + B = 3およびnカードを染色するために必要な3つの色の色の数nは、存在します。N mは、カードは方法を有するシャッフル染色プロトコルをシャッフル本質的に異なる方法の同じ数を尋ねられます。

解決策:この問題は非常に興味深いです、先輩Hzwer問題解決の参照。私はここでそれを要約します:

基本的に、我々は簡単にバーンサイドの補題とポリアの定理と考えることができ、同じ染色プログラムを参照してください、しかし、この問題はできないポリアの定理、なぜ?Ployd色染色の数は、一般的に限定されるものではないので、C ^ lはモード番号(同じプログラムがそれほど染色同じ色を有するようにので、1サイクルである)である場合、ループ部は、カラーL cである場合ため。しかし、この問題は色の数を制限する選択肢がポリD定理を使用することができないcは、各グリッドは直接いません。

だから、今、私たちは同じ色を確認する必要がありますが、サイクルの中でそれをPloydありませんか?我々は、バーンサイドの使用:そのような方法を想像して、我々は、Rが赤、Gは緑、青B、我々はそれがR / G / Bを染め選択することができ、各ループ部を有していなければなりません その後、我々は01バックパック・コンピューティング・ソリューションの数を使用することができ、RGBの容量の制約である、01バックパックモデルは、各ループ部がアイテムであることはありません。

詳細については、コードとコメントを参照してください。

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
typedefの長い 長いLL。
CONSTの INT N = 25 int型、N、R、G、B、M、P、[ 65 ]、D [ 65 ]。

ボイド exgcd(int型int型 B、INT&D、INT&X、INT&Y){ // (A、B)= GCDによって斧+ 
    なら {D =(B!); X = 1、Y = 0 ; } 
      {exgcd(B、%のB、D、Y、X)。Y- = X *(A / B)。} 
} 

BOOL VIS [ 65]; 
LL DP [ 65 ] [N] [N] [N];   // DP [L] [I]、[J] [K] LサイクルB-のRjの数Gkの一の実施形態の構成i番目の区間の代表前 
LL解決(){   // 置換基(01に相当するが、バックパックを作るために)各時間算出プログラムの数
    のためにINT I = 1 ; I <= N; I ++)VIS [I] = 0 ;
     int型 NUM = 0今、 = 1 ;
     のためのINT I = 1 {; I <= N-I ++)   // ループセクションをカウント
        IF(VIS [I])続行; 
        D [ ++ NUM] = 1 ;今= I;   // サイクル数セクション/サイズ 
        VIS [今] = 1 ;
        一方、(!VIS [今]]){ 
            D [NUM] ++ ; 
            VIS [今] = 1  = [今]。
        } 
    } 
    のためにint型、L = 0 ; L <= NUM; L ++)のためにint型 i = 0 ; I <= R; iが++)のためのINT J = 0 ; J <= G、J ++)のためのINT K = 0 ; kは<= B; ++ k個
        DP [L]を[I] [J] [K] = 0 ; 
    DP [ 0 ] [0 ] [ 0 ] [ 0 ] = 1 ;   // 初期化
    するためのint型 L = 1 ; L <= NUM L ++)   // セクションのサイクル数は、アイテムの数に対応
        するためのint型私は= 0 ; I <= R&LT ; I ++ のためのINT J = 0 ; J <= G、J ++ のためのINT K = 0 K <= B; K ++ ){
                     IF(I> = D [L])DP [L] [I] [ J] [K] =(DP [L] [I]、[J] [K] + DP 1- [ 1 ] [ID [L] [J] [K])%のP、
                     IF(J> = D [L])DP [L] [I] [J] [K] =(DP [L] [I] [J] [K] + DP 1- [ 1 ] [I] [JD [ L] [K])%のP。
                    もし(K> = D [L])DP [L] [I] [J] [K] =(DP [L] [I] [J] [K] + DP 1- [ 1 ] [I] [J ] [KD [L])%のP。
                } 
    戻り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 int型 iは= 1 ; I <= M Iは++ ){
         ためINTJ = 1。 ; J <= N; J ++)scanfの(" %のD "、&​​A [J]); 
        ANS + =(解決);   // すべての順列方式の累積数
    }
     のためのINT I = 1 ; I <= N- ; I)がA [I]を++ = I; 
    ANSは + = (解決);
     int型の X、Y、D、exgcd(第m + 1 、P、D、X、Y); 
    X =(X%P + P)%のP。   // 逆M + 1つのモジュロP決定 
    COUT ANS * Xの%P << << ; ENDL
     戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/clno1/p/11604600.html