Codeforces 509F Progress Monitoring:区间dp【根据遍历顺序求树的方案数】
题目链接:http://codeforces.com/problemset/problem/509/F
题意:
告诉你遍历一棵树的方法,以及遍历节点的顺序a[i],长度为n。
问你这棵树有多少种可能的形态。
遍历方法:
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);
题解:
表示状态:
dp[i][j] = numbers
表示a[i to j]这些节点,以a[i]为根所能构成的树的方案数。
找出答案:
ans = dp[1][n]
如何转移:
dp[i][j]一定以a[i]为根,且第一个访问的子节点一定是a[i+1]。
所以将dp[i][j]分为三部分:
(1)根节点a[i]
(2)最左边的一棵子树a[i+1 to k]
(3)右边剩下的一堆节点a[k+1 to j]
那么根据乘法原理:
dp[i][j] = ∑ dp[i+1][k]*右边一堆节点的方案数
然而遍历是根据节点编号从小到大访问儿子节点的。
这就要求,对于后面的一堆节点,如果其中某一个a[x]要和a[i+1]在同一层,那么一定要有a[i+1]<a[x]。
又因为对于右边的一堆节点来说,最先访问到的肯定是a[k+1]。
所以就是要保证:a[i+1]<a[k+1] or a[k+1]不存在
这样就不用管后面的节点了,爱咋分咋分……
接下来考虑如何求右边一堆节点的方案数。
a[k+1 to j]形成森林的方法数 = a[k to j]以a[k]为根的子树的方法数。
所以右边一堆节点的方案数 = dp[k][j]
最终就是:
if(a[i+1]<a[k+1] || k==j)
dp[i][j] += dfs(i+1,k)*dfs(k,j);
用记忆搜搞就行。
边界条件:
dp[i][i] = 1
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 505
#define MOD 1000000007 using namespace std; int n;
int a[MAX_N];
long long dp[MAX_N][MAX_N]; long long dfs(int i,int j)
{
if(i==j) return ;
if(dp[i][j]!=-) return dp[i][j];
dp[i][j]=;
for(long long k=i+;k<=j;k++)
{
if(a[i+]<a[k+] || k==j)
{
dp[i][j]+=dfs(i+,k)*dfs(k,j);
dp[i][j]%=MOD;
}
}
return dp[i][j];
} int main()
{
cin>>n;
for(int i=;i<=n;i++) cin>>a[i];
memset(dp,-,sizeof(dp));
cout<<dfs(,n)<<endl;
}
Codeforces 509F Progress Monitoring:区间dp【根据遍历顺序求树的方案数】的更多相关文章
- Codeforces 509F Progress Monitoring
http://codeforces.com/problemset/problem/509/F 题目大意:给出一个遍历树的程序的输出的遍历顺序b序列,问可能的树的形态有多少种. 思路:记忆化搜索 其中我 ...
- CodeForces 149D Coloring Brackets 区间DP
http://codeforces.com/problemset/problem/149/D 题意: 给一个给定括号序列,给该括号上色,上色有三个要求 1.只有三种上色方案,不上色,上红色,上蓝色 2 ...
- Codeforces - 149D 不错的区间DP
题意:有一个字符串 s. 这个字符串是一个完全匹配的括号序列.在这个完全匹配的括号序列里,每个括号都有一个和它匹配的括号 你现在可以给这个匹配的括号序列中的括号染色,且有三个要求: 每个括号只有三种情 ...
- codeforces 149D Coloring Brackets (区间DP + dfs)
题目链接: codeforces 149D Coloring Brackets 题目描述: 给一个合法的括号串,然后问这串括号有多少种涂色方案,当然啦!涂色是有限制的. 1,每个括号只有三种选择:涂红 ...
- Codeforces.392E.Deleting Substrings(区间DP)
题目链接 \(Description\) \(Solution\) 合法的子序列只有三种情况:递增,递减,前半部分递增然后一直递减(下去了就不会再上去了)(当然还要都满足\(|a_{i+1}-a_i| ...
- Codeforces 983B. XOR-pyramid【区间DP】
LINK 定义了一种函数f 对于一个数组b 当长度是1的时候是本身 否则是用一个新的数组(长度是原数组-1)来记录相邻数的异或,对这个数组求函数f 大概是这样的: \(f(b[1]⊕b[2],b[2] ...
- CodeForces - 1025D: Recovering BST (区间DP)
Dima the hamster enjoys nibbling different things: cages, sticks, bad problemsetters and even trees! ...
- Codeforces 1114D Flood Fill (区间DP or 最长公共子序列)
题意:给你n个颜色块,颜色相同并且相邻的颜色块是互相连通的(连通块).你可以改变其中的某个颜色块的颜色,不过每次改变会把它所在的连通块的颜色也改变,问最少需要多少次操作,使得n个颜色块的颜色相同. 例 ...
- Codeforces 958C3 - Encryption (hard) 区间dp+抽屉原理
转自:http://www.cnblogs.com/widsom/p/8863005.html 题目大意: 比起Encryption 中级版,把n的范围扩大到 500000,k,p范围都在100以内, ...
随机推荐
- struts2中配置文件加载的顺序是什么?
struts2的StrutsPrepareAndExecuteFilter拦截器中对Dispatcher进行了初始化 在Dispatcher类的init方法中定义了配置文件的加载顺序(下面是源码) p ...
- Linux下tar解压缩命令
1.打包命令: 命令格式:tar -zcvf 压缩文件名.tar.gz 被压缩文件名 可先切换到当前目录下.压缩文件名和被压缩文件名都可加入路径. 2.解包命令: 命令格式:tar -zx ...
- urllib库利用cookie实现模拟登录慕课网
思路 1.首先在网页中使用账户和密码名登录慕课网 2.其次再分析请求头,如下图所示,获取到请求URL,并提取出cookie信息,保存到本地 3.最后在代码中构造请求头,使用urllib.request ...
- Android源码下载之----内核需要另外下载
用repo sync下载的android源码默认不包含kernel目录,需要自己另外下载. 下载命令:$ git clone https://android.googlesource.com/kern ...
- uitableview滚动到最后一行
本文转载至 http://mrjeye.iteye.com/blog/1278521 - (void)scrollTableToFoot:(BOOL)animated { NSInteger s = ...
- 第二课 创建http server
nodejs 不需要单独安装服务器软件 tomcat .apache. iis 看下面的代码创建了http服务器,并输出一些简单的响应内容 //引入http 模块 var http = require ...
- Netty聊天室(2):从0开始实战100w级流量应用
目录 客户端 Client 登录和响应处理 写在前面 客户端的会话管理 客户端的逻辑构成 连接服务器与Session 的创建 Session和 channel 相互绑定 AttributeMap接口的 ...
- python 捕获异常详细信息
import os import sys import traceback BasePath = os.path.dirname(os.getcwd()) sys.path.append(BasePa ...
- threading.local的作用?
threading.local()这个方法的特点用来保存一个全局变量,但是这个全局变量只有在当前线程才能访问,如果你在开发多线程应用的时候 需要每个线程保存一个单独的数据供当前线程操作,可以考虑使用 ...
- Mysql 学习1
Mysql学习 一.数据库 1 数据库概念(了解) 1.1 什么是数据库 数据库就是用来存储和管理数据的仓库! 数据库存储数据的优先: 可存储大量数据: 方便检索: 保持数据的一致性.完整 ...