Educational DP Contest (EDPC) P ~ S 問題 解説 #AtCoder |
您所在的位置:网站首页 › edpc › Educational DP Contest (EDPC) P ~ S 問題 解説 #AtCoder |
はじめに
この記事は、EDPC の P ~ S 問題の解説です。P ~ S 問題を解いてみてから読まれることを推奨します。 Educational DP Contest / DP まとめコンテスト - AtCoderO 問題までを解いていない方は、これらの記事も読まれるといいと思います。 Educational DP Contest (EDPC) A ~ E 問題 解説 Educational DP Contest (EDPC) F ~ J 問題 解説 Educational DP Contest (EDPC) K ~ O 問題 解説 この記事の続き Educational DP Contest (EDPC) T ~ W 問題 解説 Educational DP Contest (EDPC) X ~ Z 問題 解説 P - Independent Set 問題$N$ 頂点の木の各頂点を白黒に塗り分ける方法が何通りあるか、$\mod{10^9+7}$ で求めてください。 ただし、黒で塗った頂点は隣り合ってはいけません。 制約 $1\le N\le 10^5$ 解法適当な頂点を根として、根付き木として考えます。 根付き木の各頂点について、その頂点の子についての情報から DP テーブルの値を更新していく DP は木 DP と呼ばれています。 頂点 $u$ を頂点とする部分木について、この問題と同じ問題を解くことを考えます。 $u$ に塗る色で場合分けをして考えてみます。 $u$ を白で塗る場合、$u$ の子は白黒どちらも塗ることができます。 $u$ を黒で塗る場合、$u$ の子は白で塗らなければなりません。このことから、$u$ を白で塗った時の題意を満たす通り数 $w_u$ と、黒で塗った時の通り数 $b_u$ を DP としてテーブルに保存しておけば解けます。 実装例「メモ化再帰」と言っても木上の DFS で各頂点にアクセスするのは $1$ 回だけなので、実質ただの再帰みたいなところはあります。(DP テーブル無しでも実装することができます。ぜひ挑戦してみましょう。) 計算量は $O(N)$ です。 #include #include using namespace std; const int mod = 1000000007; int N; vector G[100009]; long long white[100009], black[100009]; void dfs(int u, int p) { black[u] = 1; white[u] = 1; for(int v : G[u]) { if(v == p) continue; // 親に帰る辺は無視 dfs(v, u); black[u] *= white[v]; black[u] %= mod; white[u] *= white[v] + black[v]; white[u] %= mod; } } int main() { cin >> N; for(int i = 0; i > x >> y; x--; y--; // 0-indexed にする G[x].push_back(y); G[y].push_back(x); } dfs(0, -1); cout |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |