二つの一般的なモデル
4321 bzoj
質問の意味:人々の1からnまでの番号が付けられているがどのように多くの行法の貧しい人々のうちのいずれか2つの隣接する数字が1または-1ではないようにお願いし並んで。
N <= 1000
列挙型は、配置された:大型挿入プロセスに小さな数はDPで検討します。
; Fを[I] [j]は1〜Iの配列を示し、隣接するグループjの間の差があり、IとI-1とプログラムの数は隣接していない
私〜[I] [j]が1を表し、Gを設定します配置、隣接Jの組、及びI、および隣接スキームI-1の数との差。
私は1 +挿入位置を考慮し、転送モードの4種類があります。
1.非隣接スロットIを破壊しません
2.私を破壊し、隣接する欠員はありません
3.隣接するスロットを損傷しない私
4.破壊及びIに隣接する空孔4種(Gは、転送中にのみ起こります)。
答え:F [N] [0]
複雑:O(N ^ 2)
2560 bzoj
問題の意味:ビーズは、iとjのロープあるいはビーズの異なる部分間のC [I] [J]とNがあります。ビーズの各対の間にロープを接続しないことを選んでもよい、一つはまた、ロープが接続されて使用することを選択し、そしてビーズN図を伝達することができるどのように多くのプログラム尋ねことができます。
N <= 16
図通信はルーチンカウント:プログラムの総数は連通しない、プログラムは、ポイント1の数は、ここで通信ブロック数点の集合を列挙することができる通信しない差し引きます。プログラム番号と通信するプログラムの総数に対するポイントの残りの組の設定点と乗算されます。
セットG [S]のプログラムの総数は[S] S fは、互いに接続ポイントを設定表すポイント通信を設定プログラムの総数を表します。
Gは、[S]直接の設定点S0の最後の1に移し、G [S] = G [S0]乗法から廃棄前処理(C [I] [J] +1)(jはS0のいずれかに属し1)
O(N-2 *:Gは複雑前処理しましたN-)
F [s]は点I 1は、ケースが合法Gない点の集合を列挙しない法的減算すべてのケースがG [S]である[S ^ I] * F [i]が、このような状況減算、これは、[S] A fを得ることができます。
複雑:O(3 N-)(列挙サブセット)
#include<cstdio>
using namespace std;
const int mod=1e9+7;
int c[25][25],stack[25],F[70005],G[70005],ID[70005];
int lowbit(int x){
return x&(-x);
}
int main(){
int n;
scanf("%d",&n);
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
scanf("%d",&c[i][j]);
G[0]=1;
for (int i=0; i<n; i++) ID[1<<i]=i;
for (int i=1; i<(1<<n); i++){
int top=0;
for (int j=i; j; j-=lowbit(j)) stack[++top]=ID[lowbit(j)];
G[i]=G[i-lowbit(i)];
for (int j=2; j<=top; j++) G[i]=1ll*G[i]*(c[stack[1]][stack[j]]+1)%mod;
}
for (int i=1; i<(1<<n); i++){
F[i]=G[i];
for (int j=(i-1)&i; j; j=(j-1)&i)
if (j&lowbit(i)){
F[i]-=1ll*F[j]*G[i^j]%mod;
(F[i]+=mod)%=mod;
}
}
printf("%d\n",F[(1<<n)-1]);
return 0;
}