http://acm.hdu.edu.cn/showproblem.php?pid=5181

题意:
有一个栈,其中有n个数1~n按顺序依次进入栈顶,在某个时刻弹出。
其中m个限制,形如数字A必须在数字B之前弹出。
求方案总数
 
dp[i][j]表示数字i~j的出栈方案数
枚举最后一个出栈的数k,若k合法
dp[i][j]+=dp[i][k]*dp[k+1][j]
如何判断k是否合法?
 
对于一组i,j,k来说,它的弹出顺序是 [i,k-1]早于[k+1,j]早于k
对于一个限制 A必须在B之前出栈 
它只会对 i<=min(A,B),j>=max(A,B) 的 dp[i][j] 产生影响
若A<B,
a、i<=k<A或B<k<=j,产生的影响已在子DP中求出
b、k=A,A最后出栈,显然不合法
c、k=B,B最后出栈,显然合法
d、A<k<B,[A,k-1]早于[k+1,B]早于k出栈,所以合法
若B<A,
a、i<=k<B或A<k<=j,产生的影响已在子DP中求出
b、k=A,A最后出栈,显然不合法
c、k=B,B最后出栈,显然合法
d、B<k<A,[B,k-1]早于[k+1,A]早于k出栈,所以不合法
综上所述
对于一个限制A必须在B之前出栈
若A<B,当k=A时不合法
若B<A,当k∈(B,A]时不合法
这样的话之间复杂度时O(n^3 * m)
 
对于限制A必须在B之前出栈,如果确定了不能用k转移
考虑这些区间有哪些
令mi=min(A,B),mx=max(A,B)
那么区间
[1,mx] [1,mx+1] [1,mx+2]……[1,n]
[2,mx] [2,mx+1] [2,mx+2]……[2,n]
……
[mi][mx] [mi,mx+1] [mi,mx+2]……[mi,n]
不能用k转移
如果把这些区间的左右端点当做二维平面上的一个点对
那么这些区间就是 以[1,mx]为左上角,以[mi,n]为右下角的一个矩形
那么对于每个k,利用差分和前缀和预处理出这些矩形,就可以做到O(1)查询k转移dp[l,r]是否合法
时间复杂度为O(n^3 + nm)
 
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; const int mod=1e9+; #define N 302
#define M 90001 int n,m; int lim[M][]; int a[N][N][N]; int dp[N][N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int xl,int yl,int xr,int yr,int k)
{
a[xl][yl][k]++;
a[xl][yr+][k]--;
a[xr+][yl][k]--;
a[xr+][yr+][k]++;
} void pre()
{
memset(a,,sizeof(a));
int mi,mx;
for(int i=;i<=m;++i)
{
mi=min(lim[i][],lim[i][]);
mx=max(lim[i][],lim[i][]);
if(lim[i][]<lim[i][]) add(,mx,mi,n,lim[i][]);
else
for(int j=lim[i][]+;j<=lim[i][];++j) add(,mx,mi,n,j);
}
for(int k=;k<=n;++k)
{
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
a[i][j][k]=a[i-][j][k]+a[i][j-][k]-a[i-][j-][k]+a[i][j][k];
}
} void DP()
{
memset(dp,,sizeof(dp));
for(int i=;i<=n;++i) dp[i][i]=;
for(int i=;i<=n+;++i) dp[i][i-]=;
for(int i=n-;i;--i)
for(int j=i+;j<=n;++j)
for(int k=i;k<=j;++k)
if(!a[i][j][k])
dp[i][j]=(dp[i][j]+(long long)dp[i][k-]*dp[k+][j])%mod;
cout<<dp[][n]<<'\n';
} int main()
{
int T;
read(T);
bool tag;
while(T--)
{
read(n); read(m);
tag=true;
for(int i=;i<=m;++i)
{
read(lim[i][]),read(lim[i][]);
if(lim[i][]==lim[i][]) tag=false;
}
if(!tag) { puts(""); continue; }
pre();
DP();
}
}
 

hdu 5181 numbers的更多相关文章

  1. hdu 5181 numbers——思路+区间DP

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5181 题解:https://www.cnblogs.com/Miracevin/p/10960717.ht ...

  2. HDU.5181.numbers(DP)

    题目链接 参考. \(Description\) 将\(1,2,\cdots,n(n\leq 300)\)依次入栈/出栈,并满足\(m(m\leq 90000)\)个形如\(x\)要在\(y\)之前出 ...

  3. HDU 6168 - Numbers | 2017 ZJUT Multi-University Training 9

    /* HDU 6168 - Numbers [ 思维 ] | 2017 ZJUT Multi-University Training 9 题意: .... 分析: 全放入multiset 从小到大,慢 ...

  4. HDU 5522 Numbers 暴力

    Numbers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5522 ...

  5. hdu 5585 Numbers

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5585 思路:对于2和5只须看最后一位数,对于三看所有位的数字之和就行 #include<stdi ...

  6. hdu 5585 Numbers【大数+同余定理】

    Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  7. hdu 6168 Numbers

    Numbers Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  8. 2017 ACM暑期多校联合训练 - Team 9 1008 HDU 6168 Numbers (模拟)

    题目链接 Problem Description zk has n numbers a1,a2,...,an. For each (i,j) satisfying 1≤i<j≤n, zk gen ...

  9. HDU Humble Numbers

    Problem Description A number whose only prime factors are 2,3,5 or 7 is called a humble number. The ...

随机推荐

  1. UWP简单示例(一):快速合成音乐MV

    说明 本文发布时间较早,内容可能已过时.最新动态请关注 TypeScript 版本.(2019 年 3 月 注) 在线演示: 音频可视化(TypeScript) 准备 IDE:Visual Studi ...

  2. 虚拟机console最小化安装操作系统图文

    1. 概述2. 安装操作系统2.1 交互界面2.2 内核镜像解压等初始化2.3 磁盘发现2.4 硬件支持告警3. 开始安装3.1 语言选择3.2 键盘选择3.3 服务器类型3.4 配置主机名3.5 时 ...

  3. java后台面试知识点总结

    本文主要记录在准备面试过程中遇到的一些基本知识点(持续更新) 一.Java基础知识 1.抽象类和接口的区别 接口和抽象类中都可以定义变量,但是接口中定义的必须是公共的.静态的.Final的,抽象类中的 ...

  4. [T-ARA][내가 너무 아파][我很痛]

    歌词来源:http://music.163.com/#/song?id=5402882 作曲 : 新沙洞老虎/崔圭成 [作曲 : 新沙洞老虎/崔圭成] 作词 : 新沙洞老虎/崔圭成 [作词 : 新沙洞 ...

  5. TeamWork#3,Week5,Release Notes of the Alpha Version

    在这里的是一款你时下最不可或缺的一款美妙的产品. “今天哪家外卖便宜?” “今天这家店在哪个网站打折?” “这家店到底哪个菜好吃?” 这些问题你在寝室/办公室每天要问几次?还在为了找一家便宜的外卖店而 ...

  6. Python3的bytes和str之别

    Python3不会以任意隐式的方式混用str和bytes,正是这使得:两者的区分特别清晰,在使用Python时不能拼接字符串和字节包,也无法搜索字节包里面的字符串(反之亦然),也不能讲字符串传入参数为 ...

  7. JavaBeans与内省(Introspector)

    JavaBean与Introspector 反射和内省操作很多时候都是在以后要做框架的时候作用非常大.    现在你学的是面向对象编程,即:你所写代码都能够找到对应的类或接口,找到具体的方法写出对应的 ...

  8. Objective-C 语言特点/特性

    Objective-C中 1.所有的类都必须继承自NSObject. 2.所有对象都是指针的形式. 3.用self代替this. 4.使用id代替void*. 5.使用nil表示NULL, 6.只支持 ...

  9. Oracle Profile 的简单说明

    1. 查看已经有的oracle 的profile 首先profile的解释 我理解为 是一个 简略的配置文件, 跟linux的 bash文件的配置信息类似 bash_profile . select ...

  10. CF10D LCIS

    题意翻译 求两个串的最长公共上升子序列. 题目描述 This problem differs from one which was on the online contest. The sequenc ...