Codeforces 830D Singer House - 动态规划

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.

技术分享 Singer 4-house

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

Input
2
Output
9
Input
3
Output
245
Input
20
Output
550384565

Note

There are 9 paths in the first example (the vertices are numbered on the picture below): 1231-22-11-33-12-1-33-1-2.

技术分享 Singer 2-house

  题目大意 取一棵深度为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.

技术分享 Singer 4-house

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

Input
2
Output
9
Input
3
Output
245
Input
20
Output
550384565

Note

There are 9 paths in the first example (the vertices are numbered on the picture below): 1231-22-11-33-12-1-33-1-2.

技术分享 Singer 2-house

以上是关于Codeforces 830D Singer House - 动态规划的主要内容,如果未能解决你的问题,请参考以下文章

Singer House CodeForces - 830D (组合计数,dp)

#21 CF830D

机动目标跟踪——Singer模型

机动目标跟踪——Singer模型

Singer 学习二 使用Singer进行gitlab 2 postgres 数据转换

Singer 学习六 运行&&开发tapstargets (一 taps 运行说明)