Codeforces 830D Singer House - 動態規劃
It is known that passages in Singer house are complex and intertwined. Let‘s define a Singer k-house as a graph built by the following process: take complete binary tree of height k and add edges from each vertex to all its successors, if they are not yet present.
Count the number of non-empty paths in Singer k
Input
The only line contains single integer k (1 ≤ k ≤ 400).
Output
Print single integer — the answer for the task modulo 109 + 7.
Example
Input2Output
9Input
3Output
245Input
20Output
550384565
Note
There are 9 paths in the first example (the vertices are numbered on the picture below): 1
題目大意 取一棵深度為k的完全二叉樹,每個點向他的所有祖父連一條雙向邊,問新圖中存在多少條有向簡單路徑。
顯然動態規劃(不然你還能組合數亂搞?)
考慮用f[i][j]表示在i-house中,葉節點的j級祖先作為路徑起點的有向簡單路徑的條數。然後發現一個點從它某個祖先繞回來繞回子樹的方案數很難統計。
然後我就不會做了跑去看題解,題解用f[i][j]表示在i-house中,選取了j條會不想交的簡單有向路徑的方案數。合並的時候枚舉兩棵(i - 1)-house中的路徑數,考慮幾種情況:
1)什麽都不操作,將方案數累加到f[i][j + k]的頭上
2)加入i級祖先然後什麽都不做,將方案數累加到f[i][j + k + 1]的上
3)通過i級祖先連接一條路徑,因為可以從i級祖先連接這條路徑的起點或從它的終點到i級祖先,所以將方案數乘2累加到f[i][j + k + 1]上。
4)通過i級祖先合並任意兩條路徑(一定是可能的,因為 每個低於i級點到i級祖先都有直接的邊相連),j + k條路徑中選兩條的方案數乘方案數再乘2累加到f[i][j + k - 1]上。
(ps:以上的方案數指的是從左子樹選擇j條路徑的方案數乘從右子樹選擇k條路徑的方案數)
Code
1 /** 2 * Codeforces 3 * Problem#830C 4 * Accepted 5 * Time: 1247ms 6 * Memory: 600k 7 */ 8 #include <bits/stdc++.h> 9 using namespace std; 10 #define smplus(a, b) a = (a + b) % moder 11 12 const int moder = 1e9 + 7; 13 const int lim = 405; 14 15 int n; 16 int f[lim][lim]; 17 18 inline void init() { 19 scanf("%d", &n); 20 } 21 22 inline int C(int a) { 23 return a * (a - 1); 24 } 25 26 inline void solve() { 27 f[1][0] = f[1][1] = 1; 28 for(int i = 2; i <= n; i++) 29 for(int j = 0; j <= n; j++) 30 for(int k = 0; k <= n - j; k++) { 31 int t = (long long)f[i - 1][j] * f[i - 1][k] % moder; 32 smplus(f[i][j + k + 1], t); //把i級祖先當成一個單獨的點加入 33 smplus(f[i][j + k], t * 1LL * (((j + k) << 1) + 1) % moder); //不加入i級祖先或者連通一條路徑和i級祖先 34 if(j + k) 35 smplus(f[i][j + k - 1], t * 1LL * C(j + k)); //從j + k條路徑中選擇2條通過i級祖先合並 36 } 37 printf("%d", f[n][1]); 38 } 39 40 int main() { 41 init(); 42 solve(); 43 return 0; 44 }
It is known that passages in Singer house are complex and intertwined. Let‘s define a Singer k-house as a graph built by the following process: take complete binary tree of height k and add edges from each vertex to all its successors, if they are not yet present.
Count the number of non-empty paths in Singer k-house which do not pass the same vertex twice. Two paths are distinct if the sets or the orders of visited vertices are different. Since the answer can be large, output it modulo 109 + 7.
Input
The only line contains single integer k (1 ≤ k ≤ 400).
Output
Print single integer — the answer for the task modulo 109 + 7.
Example
Input2Output
9Input
3Output
245Input
20Output
550384565
Note
There are 9 paths in the first example (the vertices are numbered on the picture below): 1, 2, 3, 1-2, 2-1, 1-3, 3-1, 2-1-3, 3-1-2.
Codeforces 830D Singer House - 動態規劃