Codeforces 509F Progress Monitoring (区间dp 或 记忆化搜索)
来源:互联网 发布:java 唤醒sleep的线程 编辑:程序博客网 时间:2024/04/29 22:50
F. Progress Monitoring
time limit per test 1 second
memory limit per test 256 megabytes
Programming teacher Dmitry Olegovich is going to propose the following task for one of his tests for students:
You are given a tree T with n vertices, specified by its adjacency matrix a[1... n, 1... n]. What is the output of the following pseudocode?
used[1 ... n] = {0, ..., 0};
procedure dfs(v):
print v;
used[v] = 1;
for i = 1, 2, ..., n:
if (a[v][i] == 1 and used[i] == 0):
dfs(i);
dfs(1);
In order to simplify the test results checking procedure, Dmitry Olegovich decided to create a tree T such that the result is his favorite sequence b. On the other hand, Dmitry Olegovich doesn't want to provide students with same trees as input, otherwise they might cheat. That's why Dmitry Olegovich is trying to find out the number of different trees T such that the result of running the above pseudocode with T as input is exactly the sequence b. Can you help him?
Two trees with n vertices are called different if their adjacency matrices a1 and a2 are different, i. e. there exists a pair (i, j), such that 1 ≤ i, j ≤ n and a1[i][j] ≠ a2[i][j].
Input
The first line contains the positive integer n (1 ≤ n ≤ 500) — the length of sequence b.
The second line contains n positive integers b1, b2, ..., bn (1 ≤ bi ≤ n). It is guaranteed that b is a permutation, or in other words, each of the numbers 1, 2, ..., n appears exactly once in the sequence b. Also it is guaranteed that b1 = 1.
Output
Output the number of trees satisfying the conditions above modulo 109 + 7.
Sample test(s)
input
3
1 2 3
output
2
input
3
1 3 2
output
1
题目链接:http://codeforces.com/problemset/problem/509/F
题目大意:给一个序列b[i],问通过题目所给伪代码深搜出来遍历路径和序列b[i]相同的树有多少种,结果对1e9 + 7取余
题目分析:两种姿势区间dp和记忆化搜索,其实原理都一样。
先说记忆化搜索解法:
由于题目说了b1肯定等于1,也就是根确定,因为要按照1,2...n的顺序深搜,我们可以取一段区间,开始就是1到n,进行深搜,我们按照增序来找
1.因为根为1即b[1]=1,b[i]又是一个排列,所以b[2]必然大于1,我们直接从b[2]开始往后比,当满足b[l + 1] < b[i + 1]时,子树可以继续分解,分解成两部分,显然一部分把l+1当作根,另一部分把i当作根,根据乘法原理
ans = (ans + DFS(l + 1, i) * DFS(i, r))
2.当i == r时,最右端的端点可以单独成一棵子树,例如4 1 2 4 3这个3可以单独当作右子树,而4 1 4 3 2我们不能把3 2部分单独放在右子树,因为这样必有和4在同一层的,4肯定后访问了,如果l==r则说明找到了一组子树情况
#include <cstdio>#include <cstring>#define ll long longint const MAX = 505;int const MOD = 1e9 + 7;ll dp[MAX][MAX];int b[MAX];ll DFS(int l, int r) { ll ans = dp[l][r]; if(ans >= 0) return ans; if(l == r) return 1; ans = 0; //表示每一个子树的合法方案数 for(int i = l + 1; i <= r; i++) if(i == r || b[l + 1] < b[i + 1]) ans = (ans + DFS(l + 1, i) * DFS(i, r)) % MOD; dp[l][r] = ans % MOD; return ans % MOD;}int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &b[i]); memset(dp, -1, sizeof(dp)); int res = DFS(1, n); printf("%d\n", res);}
区间dp解法:
其实就是把记忆化搜索的递归改成递推,就是区间dp咯,dp[i][j]表示以i为根到j位置这个区间构成的子树的方案数。
转移方程:(i == r || b[l + 1] < b[i + 1]) i: [l + 1, r] dp[l][r] = dp[l][r] + dp[l + 1][i] * dp[i][r] ,可以发现与递归一样,不过速度显然递推快
#include <cstdio>#include <cstring>#define ll long longint const MOD = 1e9 + 7;int const MAX = 505;int b[MAX];ll dp[MAX][MAX];int main(){ int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &b[i]); memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) dp[i][i] = 1ll; for(int len = 1; len < n; len++) { for(int l = 1; l + len <= n; l++) { int r = l + len; for(int i = l + 1; i <= r; i++) if(i == r || b[l + 1] < b[i + 1]) dp[l][r] = (dp[l][r] + dp[l + 1][i] * dp[i][r]) % MOD; } } printf("%I64d\n", dp[1][n]);}
- Codeforces 509F Progress Monitoring (区间dp 或 记忆化搜索)
- codeforces 509F Progress Monitoring (区间dp)
- codeforces 509F F. Progress Monitoring(区间dp)
- Progress Monitoring - CodeForces 509 F dp
- Codeforces 509F Progress Monitoring 给定dfs序求树的同构数 区间dp
- codeforces 509F Progress Monitoring
- 【CodeForce】509F Progress Monitoring(树形情景区间DP)
- Codeforces Round #289 (Div. 2, ACM ICPC Rules) F. Progress Monitoring 区间dp
- 记忆化搜索或区间DP——石子合并
- HDU3427 Clickomania【记忆化搜索】【区间DP】
- 记忆化搜索求解区间型dp
- poj1390区间dp+记忆化搜索
- 记忆化搜索 区间dp uva629
- [CDOJ1321]-区间DP(记忆化搜索)
- Codeforces Round #106(Div. 2) 149D. Coloring Brackets 区间DP 记忆化搜索
- CodeForces 149D Coloring Brackets(记忆化搜索区间dp)【多做】
- codeforces 149D Coloring Brackets (区间DP OR 记忆化搜索 总结!!!)
- CodeForces 149D Coloring Brackets(区间dp+记忆化搜索)
- atitit.spring hibernate的事务机制 spring不能保存对象的解决
- 职场菜鸟,自己不擅长的工作任务压到身上,该怎么应对?
- self-introduction
- poj2892 treap
- 神奇的自慰帽子
- Codeforces 509F Progress Monitoring (区间dp 或 记忆化搜索)
- Hash Table (youtube)
- bzoj1503 treap
- Android图形显示系统——下层显示3:窗口系统
- AC大牛经典语录
- HDU 4089 Activation (概率dp 好题 + 难题)
- Pure : 来自雅虎的纯 CSS 框架
- IOS 开发进阶--多线程和网络--pthread
- ajax跨域访问 JQuery 的跨域方法