修正前の問題文:「a,b,c,dが相異なる」の場合
以下の条件を満たす通り数dp[n]を考える
1:n人存在する
2:n人全てが、いずれかの人と赤or青の糸で結ばれている
3:問題の2条件と最終的な状態の条件を満たす。
以上を満たすdp[n]が求まれば、元の問題の答えは
ans=ΣBinom(15,i)*dp[i]になるのは明らか。
dp[n]を具体的に考えていく。
a < b < cに対して
人aと人cが間接的(直接も含む)に結ばれている場合
人bも人a、人cと間接的(直接も含む)に結ばれているのは明らか
(最終的な状態を満たさなくなるため)
つまりn人は間接的に結ばれている人の集合で分割されることがわかる。
以下の条件を満たす通り数subdp[n]を考える
1:n人存在する
2:n人全てが、間接的(直接も含む)に結ばれている
3:問題文の2条件と最終的な状態の条件を満たす。
これを求めることができれば、dp[i] = Σsubdp[i-j]dp[j]でdpが求まる。
subdp[n]について考える
n= 1の時subdp[n] = 0は明らか
n= 2の時subdp[n] = 2は明らか
n= 3の時
1-2-3
1-3-2
2-1-3の結び方が条件を満たすためsubdp[n] = 6
n>3の時
1-2-3........(n-1)-n
2-1-3-......(n-1)-n
1-2-3........-n-(n-1)
2-1-3........-n-(n-1)の結び方が条件を満たすためsubdp[n] = 8
となる。
よってdp[n]が求まり元問題の答えも求まった。
※subdp[n] = 2 (n>=2)とすると修正後の問題の答えとなる
void omc130b(int n) {//本問は n= 15 vector<long long>dp(n + 1); dp[0] = 1; rep2(i, 1, n + 1) { if (i >= 2)dp[i] += dp[i - 2] * 2; if (i >= 3)dp[i] += dp[i - 3] * 6; rep(j, i - 3)dp[i] += dp[j] * 8; } long long ans = 0; rep(i, n + 1)ans += Binom[n][i] * dp[i]; cout << ans << endl; }