『count 区间dp』
<更新提示>
<第一次更新>
<正文>
count
Description
既然是萌萌哒 visit_world 的比赛,那必然会有一道计数题啦!
考虑一个N个节点的二叉树,它的节点被标上了1-N的编号. 并且,编号为i的节点在二叉树的前序遍历中恰好是第i个出现.
我们定义Ai表示编号为i的点在二叉树的中序遍历中出现的位置.
现在,给出M个限制条件,第i个限制条件给出了ui,vi,表示 Aui<Avi,也即中序遍历中ui在vi之前出现.
你需要计算有多少种不同的带标号二叉树满足上述全部限制条件,答案对\(10^9+7\)取模.
Input Format
第一行一个整数T(1≤T≤5), 表示数据组数.
每组数据第一行为两个整数N,M,意义如题目所述.
接下来M行,每行两个整数ui,vi(1≤ui,vi≤N) , 描述一条限制。
Output Format
对每组数据,输出一行一个整数,表示答案.
Sample Input
3
5 0
3 2
1 2
2 3
3 3
1 2
2 3
3 1
Sample Output
42
1
0
解析
我们知道一个前序遍历和一个中序遍历可以唯一确定一棵二叉树,也就是让我们求前序遍历在满足\(m\)个限定要求下可以对应多少个中序遍历。
考虑区间\(dp\),\(f[l][r]\)代表前序遍历的区间为\([l,r]\),\(l\)为根节点的子树中对应的方案数。
如果没有限制,直接考虑划分子树的方式划分区间,转移累加方案数即可。有限制时,也就是有些转移不能执行了,我们可以把限制打在一个二维数组里,求一下二维前缀和实现矩阵求和。这样转移时的限制查询就可以变成某个矩阵的求和了,若有值就说明存在若干限制,不能转移。
\(Code:\)
#include <bits/stdc++.h>
using namespace std;
const int N = 420 , Mod = 1e9+7;
int n,m,s[N][N];
long long f[N][N];
inline void input(void)
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        s[x][y] ++;
    }
}
inline int calc(int x1,int y1,int x2,int y2) { return s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1]; }
inline void init(void)
{
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            s[i][j] += s[i][j-1];
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            s[i][j] += s[i-1][j];
}
inline void add(long long &a,long long b) { a += b; if ( a >= Mod ) a -= Mod; }
inline void dp(void)
{
    for (int i=1;i<=n;i++) f[i][i] = 1;
    for (int len=2;len<=n;len++)
        for (int l=1,r;(r=l+len-1)<=n;l++)
        {
            if ( calc( l , l+1 , l , r ) == 0 )
                add( f[l][r] , f[l+1][r] );
            if ( calc( l+1 , l , r , l ) == 0 )
                add( f[l][r] , f[l+1][r] );
            for (int k=l+1;k<=r-1;k++)
                if ( calc( l , l+1 , l , k ) == 0 && calc( k+1 , l , r , k ) == 0 )
                    add( f[l][r] , 1LL * f[l+1][k] * f[k+1][r] % Mod );
        }
}
int main(void)
{
    freopen("input.in","r",stdin);
    freopen("output.out","w",stdout);
    int T;
    scanf("%d",&T);
    while ( T --> 0 )
    {
        memset( f , 0 , sizeof f );
        memset( s , 0 , sizeof s );
        input();
        init();
        dp();
        printf("%lld\n",f[1][n]);
    }
    return 0;
}
<后记>
『count 区间dp』的更多相关文章
- 『Blocks 区间dp』
		Blocks Description Some of you may have played a game called 'Blocks'. There are n blocks in a row, ... 
- 『金字塔 区间dp』
		金字塔 Description 虽然探索金字塔是极其老套的剧情,但是这一队 探险家还是到了某金字塔脚下.经过多年的研究,科 学家对这座金字塔的内部结构已经有所了解.首先, 金字塔由若干房间组成,房间之 ... 
- 『大 树形dp』
		大 Description 滑稽树上滑稽果,滑稽树下你和我,滑稽树前做游戏,滑稽多又多.树上有 n 个节点,它们构成了一棵树,每个节点都有一个滑稽值. 一个大的连通块是指其中最大滑稽值和最小滑稽值之差 ... 
- 『kamp 树形dp』
		kamp Description jz 市的云台山是个很美丽的景区,小 x 暑期到云台山打工,他的任务是开景区的大巴. 云台山景区有 N 个景点,这 N 个景点由 N-1 条道路连接而成,我们保证这 ... 
- 『字符合并 区间dp 状压dp』
		字符合并 Description 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这 k 个字符确定.你需要求出你能获得的最大分 ... 
- 『土地征用  Land Acquisition 斜率优化DP』
		斜率优化DP的综合运用,对斜率优化的新理解. 详细介绍见『玩具装箱TOY 斜率优化DP』 土地征用 Land Acquisition(USACO08MAR) Description Farmer Jo ... 
- 「学习笔记」动态规划 I『初识DP』
		写在前面 注意:此文章仅供参考,如发现有误请及时告知. 更新日期:2018/3/16,2018/12/03 动态规划介绍 动态规划,简称DP(Dynamic Programming) 简介1 简介2 ... 
- P1040 加分二叉树   区间dp
		题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ... 
- 『Python基础-4』字符串
		# 『Python基础-4』字符串 目录 1.什么是字符串 2.修改字符串 2.1 修改字符串大小 2.2 合并(拼接)字符串 2.3 使用乘号'*'来实现字符串的叠加效果. 2.4 在字符串中添加空 ... 
随机推荐
- nginx缓存页面后,串会话问题的解决方案
			用的Nigix 后面挂了二个Tomcat是springMVC session存在Redis的项目 但是上线以后反应A用户添加数据,变成B用户的,网上查的方案如下: 解决方案,nginx提供prox ... 
- PHP json中文
			json_encode 和 json_decode 只支持utf-8编码的字符串,GBK的字符串要用json就得转换成utf-8字符串 看效果 <?php header("Conten ... 
- 【原】Spring测试类代码
			package test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.bea ... 
- flink Periodic Watermarks 自定义周期性水印
			1.BoundedOutOfOrdernessGenerator /** * This generator generates watermarks assuming that elements ar ... 
- Scrum冲刺第四篇
			一.每日例会 会议照片 成员 昨日已完成的工作 今日计划完成的工作 工作中遇到的困难 陈嘉欣 撰写博客,管理成员提交代码 和队友一同开发音乐控制模块 对音频控制方面知识了解少,功能实现困难 邓镇港 帮 ... 
- 记一条复杂的PHP中写的关于查询的mysql语句
			$sql="select p.*,q.md from xz_laptop as p inner join xz_laptop_pic as q on p.lid=q.lid title li ... 
- liteos错误处理(十一)
			1. 概述 1.1 基本概念 错误处理指用户代码发生错误时,系统调用错误处理模块的接口函数,完成上报错误信息,并调用用户自己的钩子函数,进行特定的处理. 错误处理模块实现OS内部错误码记录功能.OS内 ... 
- [基础]斯坦福cs231n课程视频笔记(二) 神经网络的介绍
			目录 Introduction to Neural Networks BP Nerual Network Convolutional Neural Network Introduction to Ne ... 
- Win7共享只看到部分文件
			把192.168.70.88这台机器的Android目录做为共享文件夹. 共享端:windows server 用户端:其它pc机安装windows7 或windows 10 在用户端只能看到部分文件 ... 
- pdfium
			https://github.com/SubtleCow/AccessControlListsintheDOM/tree/4673d995e5614bc682cecd22f9b2919b2360273 ... 
