【CodeForce】509F Progress Monitoring(树形情景区间DP)
来源:互联网 发布:二分搜索算法代码 编辑:程序博客网 时间:2024/05/17 03:38
题目大意:有一段深搜的代码,是遍历一个邻接矩阵,然后输出一个序列,这个邻接矩阵的原形是一棵树,那么现在就是要你根据序列,求出最多有多少个不同的树遍历之后可以得到相同的序列。
思路:这道题属于简单的区间DP,仔细点想就可以了。
第一种方法也是最直接的思路。
令dp[i][j]表示的是以i这个点为根,其余点为它的子树时,符合条件的最大个数。
从样例可以想到
1 2 3由于3和2交换之后,依然不会影响输出,所以假如1 2 xxx 3xxx,交换2,3节点下的树,也是不会影响序列的。
突破点就在此,dp[i][j]表示的便是一棵以i为根的(子)树,我们要做的就是去比较子树根的大小,判断可以不可以交换。
这边还需明白的一点在于:dp[i][j]表示以i为根的情况,dp[i-1][j]表示的便是i-j中的节点有任意多个节点在同一层的情况。(这个也不知道怎么讲- -!)
第一种方法的状态转移方程:dp[i][j]=dp[i][j]+dp[i+1][k]*dp[k][j](d[k+1]>d[i+1]),这边主要要理解的是不同子树的根能否位于同一层的情况。
AC代码:
#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<cstdio>#include<cstring>using namespace std;long long dp[505][505];int d[505];#define mod 1000000007;/*dp[i][j]表示i为根时符合条件的情况,最直接的设想。*/int main(){int n;while (cin >> n){for (int i = 1; i <= n; i++)scanf("%d", &d[i]);memset(dp, 0, sizeof(dp));for (int i = 1; i <= n; i++)dp[i][i] = dp[i][i + 1] = 1;for (int len = 2; len < n;len++)for (int i = 1; i + len <= n; i++){int j = i + len;for (int k = i + 1; k <=j;k++)if (k==j||d[k+1]>d[i+1])//k==j是考虑最后一个顶点单独为一个第二层子树的情况{dp[i][j] += dp[i + 1][k] * dp[k][j];dp[i][j] %= mod;}}cout << dp[1][n] << endl;}}
第二种方法:
其实第二种方法跟第一种方法一样,只是表示上没那么直接
dp[i][j]表示的是i-j中的节点有任意多个节点在同一层的情况很明显这边的根便是i-1,并且先输出的是i,
所以最终的结果是dp[2][n+1]
AC代码:
/*dp[i][j] 表示的是i-j当中符合输出序列的树的个数,但需要注意的是这边的i不一定为根,还包括i与i+1-j同一层的情况,需好好理解。*/int main(){int n;while (cin >> n){for (int i = 1; i <= n; i++)scanf("%d", &d[i]);memset(dp, 0, sizeof(dp));for (int i = 1; i <= n + 1; i++)dp[i][i] = dp[i][i + 1] = 1;for (int len = 2; len <=n;len++)for (int i = 1; i + len <= n+1; i++){int j = i + len;dp[i][j] += dp[i + 1][j];//i单独为节点的情况for (int k = i + 1; k < j;k++)if (d[i] < d[k])//两者的差别在于判断条件。{dp[i][j] += dp[i + 1][k] * dp[k][j];//因为i为节点,所以这个树有dp[i+1][k]种情况dp[i][j] %= mod;}}cout << dp[2][n+1] << endl;}}
0 0
- 【CodeForce】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 (区间dp 或 记忆化搜索)
- codeforces 509F Progress Monitoring
- Codeforces Round #289 (Div. 2, ACM ICPC Rules) F. Progress Monitoring 区间dp
- Codeforce 581F(树形dp)
- Codeforce 219D(树形dp)
- Codeforce 490E(树形dp)
- Codeforce 486D(树形dp)
- codeforce 149D:Coloring Brackets(区间dp)
- Codeforce 337D 容斥+树形dp
- CF 581F 树形dp
- 树形dp-CodeForces 581F
- Vijos P1100 加分二叉树(区间DP,树形DP)
- codeforce Ilya and Roads (区间dp)
- LR对事务状态的跟踪
- Spring进阶—如何用Java代码实现邮件发送(二)
- UVA - 11538 - Chess Queen (数论~)
- 使用随机文件流类RandomAccessFile将一个文本文件倒置读出。
- Linux系统调用--fcntl函数详解
- 【CodeForce】509F Progress Monitoring(树形情景区间DP)
- Best Time to Buy and Sell Stock III (Java)
- shell写的日期函数
- oracle一个创建用户、创建表空间、授权、建表的完整过程
- linux的open函数
- CORS(跨域资源共享) 的配置
- Java String面试题
- 从相册中取图片奔溃问题解决
- Ant自动编译打包&发布 android项目