[説明] POJ_1417_(互いに素なセット\リュック

https://blog.csdn.net/qq_34731703/article/details/54603652

1.変換:はい言っ両側同じ、または異なるクラス(本当にカイ

大きさが正確にこれらのコレクションとP1を選択するようになりました小さなセットで大規模なコレクションのそれぞれから選出された2パートコレクション内のトピックのセットにいくつかの変更は、ありますが、一つだけのプログラムは、(それぞれを決定するためにあります誰要素があります

だから、実現可能性DPを行い、我々はプログラムの数、セットの$ F [i] [j]は、私はプログラムの数を$最初の$のための$が$ jは$を構成するを記録し、明らかに移します

しかし、出力方式に、原因で大出力の数、および各小コレクションに小さなの要件に、そこに多くの要素があるので、私はどこ転送を記録することはありませんが、$ fで[I-1]〜[J-サイズ]は$プログラム番号です1は、それが1であれば、これは間違いなくに転送され、そして暴力のすべての要素を列挙し、選出されたセットに属し

#include <iostreamの> 
する#include <アルゴリズム> 
の#include <cstdioを> 
する#include <CStringの>
 使用して 名前空間STD。
const  int型 MAXN = 1009 ;
int型nは、P1、P2;
INT FA [MAXN]、D [MAXN]、W [ 2 ] [MAXN]、V [MAXN]、P [MAXN]。
インラインINT検索(INT X){
     場合(X == FA [X])戻りX。
    INT RT = (FA [X])を見つけます。
    D [X] ^ = D [FA [X]]。
    戻り [X] = FAを室温; 
} 
インラインボイドunionn(int型のx、int型の Y、int型K){
     int型 XX =(X)を求めるYY = (y)を見つけます。
    もし(XX == YY)のリターン; 
    FA [XX] = YY。
    D [XX] = D [X] ^ D [Y] ^ K。
} 
INT F [MAXN] [MAXN]。
INT メイン(){
     ながら(scanf関数(" %D%D%D "、&​​N、&P1&P2)&&(N + P1 + P2)){
         ためint型 I = 1 ; I <= P1 + P2; I ++)は、FA [I] = I。
        memsetの(D、0はsizeof(d)参照)。
        memset(V、0はsizeof (V))。
        memset(W 0はsizeof (W))。
        memsetの(F、0はsizeof (F))。
        チャー S [ 10 ]。
        以下のためにint型 iは= 1 ; iがn = <;、X、Y iは++ ){ 
            scanf関数(" %D%D%S "、およびX&Y、S)。
            もし(S [ 0 ] == ' Y ')unionn(X、Y、0 );
             unionn(X、Y、1 )。
        } 
        //暴力找每个小集合
        INT CNT = 0 以下のためにint型 iは= 1 iは++; iが<= P1 + P2 であれば(!{V [i])と
             ++ CNT。
            int型 FF = (i)を見つけます。
            以下のためのint型 J ++; J <= P1 + P2 J = の場合(!見つける(J)== FF && V [J])V [J] = 1、W [D [J]] [CNT] + + ; 
            P [CNT] =のFF。
        } 
        // のDP 
        F [ 0 ] [ 0 ] = 1ために;
        int型 I = 1 iは++; iは= CNTを< ){
             int型の FLR =分(W [ 0 ] [I]、W [ 1 ] [I])。
            INT J = P1; J> = FLR; j-- ){
                 場合(F [I- 1 ] [JW [ 0 ] [I]]){ 
                    F [I] [J] + = F [I- 1 ] [JW [ 0 ] [I]]。
//                     [I] [J] = JWから[0] [i]は、
                }
                 もし([I-F 1 ] [JWは[ 1 、{] [I])
                    F [I] [J] 1+ = [I-F] [JW [ 1 ] [I]]。
//                     [I] [J] = JWから[1]〜[I]。
                } 
            } 
        } 
        もし、(F [CNT] [P1] =!1 ){ 
            のprintf(" なしの\ n "); 続け; 
        } 
        // 统计答案
        INT ANS [MAXN]、TOT = 0、MJ = P1。
        以下のためにint型私は= CNTを、I> = 1 ; i-- であれば(F [I- 1 ] [MJ-W [ 0 ] [i]は] == 1 ){
             INTの J = 1 ; J <= P1 + P2; J ++ 場合(見つける(J)== P [i]は&& D [j] == 0)ANS [++ TOT = J。
            MJ - = W [ 0 ] [i]は、
        } 
        {
             ためのint型 J = 1 ; J <= P1 + P2; J ++ 場合(見つける(J)== P [i]は&& D [J] == 1)ANS [++ TOT = J。
            MJ - = W [ 1 ] [i]は、
        } 
        ソート(ANS + 1、ANS + 1 + TOT)。
        以下のためのint型 iは= 1、I <= TOT; iは++)のprintf(" %Dを\ n " 、ANS [I])を 
        printf(" 最後の\ nを" ); 
    } 
}

 

おすすめ

転載: www.cnblogs.com/superminivan/p/11545474.html