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. Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果

    Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果 梗概: 一. 摄像机围绕目标物体旋转, 即摄像机离目标物体有一定的距离且旋转轴心为该物体的位置. 二. 当目标物体被障碍物挡住后, 需要将摄像机 ...

  2. 火狐浏览器之伪造IP地址

    前言: 前段时间,测试过程中需要伪造来源IP地址,百思不得其解,因而发现火狐浏览器的这个Modify Headers插件,十分好用,推荐给大家. 步骤: 1.安装插件Modify Headers 进入 ...

  3. 《Linux内核分析》第五周学习总结 扒开系统调用的三层皮(下)

    扒开系统调用的三层皮(下) 郝智宇 无转载 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给Men ...

  4. 《Linux内核分析》第三周

    [李行之原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] <Linux内 ...

  5. 一个java实现的简单的4则运算器

    有些基础知识有欠缺,补一下,顺便练习一下java import com.sun.deploy.util.ArrayUtil; import java.util.*; public class Main ...

  6. C#获取每月最后一天或者最末一天的方法

    /// <summary> /// 取得某月的第一天 /// </summary> /// <param name="datetime">要取得 ...

  7. 软件工程课程设计——第一个Spring

    开发会议框架表格: 1.我们团队Reborn针对需求功能进行热烈的讨论会议,从功能的方面分析开发,结合在一起组合为App软件,再另外思考附加的功能性娱乐项目. 2.开发过程中,以表格的形式反思开发过程 ...

  8. OpenFlow PacketOut消息机制

    OpenFlow PacketOut消息机制 前言 由于最近实验的进行,遇到一个比较棘手的问题,就是利用控制器主动发送packet消息的问题,期间遇到一些问题,后来在RYU群中得到群友左木的帮助成功解 ...

  9. WC----命令行实现对文件信息的统计

    需求分析: 程序处理用户需求的模式为: wc.exe [parameter][filename] 在[parameter]中,用户通过输入参数与程序交互,需实现的功能如下: 1.基本功能 支持 -c ...

  10. React组件继承的由来

    没有显式继承的时候我们这么写: import * as React from "react"; export interface HelloProps { compiler: st ...