#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 / * 不完全少しあいまいな質問の意味、敵が選択を選択する方法を知りません。 私たちの敵と選択された候補者は、選挙が同じ順序ではないと私たちはヒーローが動作しないよう選択した場合でも、仮定します 禁止限り、英雄を禁止し、その後、我々は、彼らが状況の同じ種類であることを言います この質問は、順列に変わります 私たちは、人々が最初に来ることを選択した後、A(95.5)* C(90,5)* C(85,5)を取ります どのように私はオプションを置く人々の組み合わせの数を計算します 圧力DPのように DP [I] [j]は、i番目の主人公から選ば、我々は順列組成物のJ番号5のヒトのケースを選択したかどうかを示し jは、選挙の5ヒト症例を表すためにバイナリに変換され、0の代表的な選択には選挙がないことを意味します どちらの場合も、 このヒーローを選択してください (J&1 << K && S [k]は[I])場合 DP [I] [J] = MAX(DP [I]、[J]、DP [I-1]〜[J ^(1 << K)] + DP [I] [J])%MOD。 チェックを外し DP [I] [J] = MAX(DP [I]、[J]、DP [I] [J] + DP [I-1] [j])%MOD。 * / typedefは長い 長いLL。 const int型 MAXN = 109 ; LL DP [MAXN] [(1 << 5)+ 10 ]。 INT S [ 6 ] [MAXN]。 LL MOD = 1000000007 ; LL(LL N、LLのM) { LL和 = 1 。 用(LL I = N; I> NM; i-- ) 合計 =合計* I。 戻り値の合計。 } LL C(LL N、LLのM) { LL和 = 1 。 用(LL I = 1 ; I <= M; iは++ ) 合計 =合計*(N-I + 1)/ I。 戻り値の合計。 } int型のmain() { // サンプル入力の複数のダイセット ながら(〜scanfの(" %1D "、&S [ 1 ] [ 1 ])) { ための(int型、J = 2、J <= 100 ; J ++)のscanf(" %1D "、&S [ 1 ] [J])。 以下のために(int型 I = 2、iは<= 5 ; I ++ ) のための(INT J = 1 ; J <= 100 ; J ++ ) scanf関数(" %1D "、&S [I] [J])。 memsetの(DP、0、はsizeof (DP))。 以下のために(int型 i = 0 ; iは< 5 ; I ++ ) 場合(S [iが+ 1 ] [ 1 ])DP [ 1 ] [ 1 << I] = 1 。 DP [ 1。 [] 0 ] = 1 ; // DP [0] [0] = 1; // 両方の方法を動作 するための(INT I = 2 ; I <= 100 ; I ++ ) のための(INT J = 0。 J <(1 << 5。); J ++ ) { 用(int型のk = 0 ; K < 5 ; kは++ ) { もし((J&(1 << k))を&& S [K + 1 ] [i])と DP [I] [J] =(DP [I- 1 ] [J ^(1 << K)] + DP [I] [J])%MOD。 } DP [I] [J] =(DP [I] [J] + DP [I- 1 ] [j])%MOD。 } LL ANS = DP [ 100 ] [(1 << 5) - 1 ]。 ANS =(ANS * A(95、5))のV%×((C(90、5)は、V *の%のC(85、5))%のV)。 printf(" %LLDする\ n "、ANS%のMOD)。 } リターン 0 ; }