numbers

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 196608/196608 K (Java/Others)
Total Submission(s): 154    Accepted Submission(s): 46

Problem Description
Now you have a stack and n numbers 1,2,3,…,n. These n numbers are pushed in the order and popped if the number is at the top of the stack. You can read the sample to get more details.
This question is quite easy. Therefore I must give you some limits.
There are m limits, each is expressed as a pair<A,B> means the number A must be popped before B.
Could you tell me the number of ways that are legal in these limits?
I know the answer may be so large, so you can just tell me the answer mod 1000000007(109+7).
Input
The first line contains an integer T(about 5),indicating the number of cases.
Each test case begins with two integers n(1≤n≤300) and m(1≤m≤90000).
Next m lines contains two integers A and B(1≤A≤n,1≤B≤n)
(P.S. there may be the same limits or contradict limits.)
Output
For each case, output an integer means the answer mod 1000000007.
Sample Input
5
1 0
5 0
3 2
1 2
2 3
3 2
2 1
2 3
3 3
1 2
2 3
3 1
Sample Output
1
42
1
2
0

Hint

The only legal pop-sequence of case 3 is 1,2,3.
The legal pop-sequences of case 4 are 2,3,1 and 2,1,3.

Source
题目大意:一个由1,2,......,n组成的排列,顺次插入栈中,你可以选择在任意时刻弹出栈顶元素,现在有m个要求,要求x必须在y之前出栈,问有多少种合法的出栈顺序.
分析:好题!
   先考虑没有要求的情况. 很显然就是卡特兰数. 可以用区间dp的方法去做:f[i][j] = Σf[i][k - 1] * f[k + 1][j],枚举的k是区间[i,j]中最后被弹出的元素,那么肯定先是区间[i,k-1]的元素被弹出,然后就是区间[k+1,j]的元素被弹出,最后是k被弹出.这是O(n^3)的做法
   如果有限制怎么办呢?能不能在原有的dp方案的基础上改进一下呢? 可以往两个方向思考,要么是给状态加上一维,要么是就沿用这个状态,把不满足限制的方案给排除掉. 加上一维是不现实的,因为复杂度已经达到了O(n^3),加上一维的话复杂度肯定会再上升一个级别.
   那就考虑如何把不满足限制的方案给排除掉.假设x必须要在y之前弹出,令x,y的较小值为min,较大值为max.对于x,y的限制,影响的只有包含x,y这两个点的区间,也就是区间左端点在[1,min],右端点在[max,n]的区间. 
   若x < y,那么x在排列中的位置肯定在y前面.前面说过元素弹出的顺序,如果k在x,y右边或者左边,那么作为一个子问题已经被解决了.如果k在x,y中间.只要k不是x,x永远比y先弹出. 那么对于被x,y影响的区间,一旦k = x,就不能统计进入答案中.
   若x > y,y在左边了.考虑k在y,x中间的情况.k 可以等于 y,这样y在x之后被弹出,但是一旦 y + 1 ≤ k ≤ x,则k是不合法的.
   预处理出不合法的状态是O(n^2m)的复杂度,显然是不可以接受的,怎么优化呢?
   k是要枚举的,但是区间的左右端点所在的区间是确定的,需要做的就是把这些区间快速打上标记.做法还是比较难想到的.
不合法的区间形如:[1,max],[1,max + 1],......,[1,n],[2,max],[2,max + 1],......,[min,n]. 对于二元组,一个处理方法是放到平面直角坐标系上,然后可以发现,这些点所形成的图形是一个矩形. 批量修改一个矩形,怎么快速改? 二维差分!怎么查询单个点的答案?前缀和!问题就这样被解决了.
   总复杂度O(n^3 + n*m).
   这道题综合了许多知识,把问题简化,得到一个做法后该如何推导出原问题的做法?能不能用上简化的问题的做法?如何快速修改左右端点所在区间都知道的所有区间?遇到二元组要怎么处理?如何快速修改一个矩形内所有点的值?如何查询单点答案?这就是这道题的思路.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll;
const ll maxn = ,mod = 1e9+;
ll f[maxn][maxn];
int T,n,m,sum[maxn][maxn][maxn],a[maxn][maxn][maxn];
bool flag = true; struct node
{
int x,y;
} e[]; void add(int x3,int y3,int x4,int y4,int k)
{
sum[x3][y3][k]++;
sum[x4 + ][y4 + ][k]++;
sum[x4 + ][y3][k]--;
sum[x3][y4 + ][k]--;
} void pre()
{
for (int i = ; i <= m; i++)
{
ll x = e[i].x,y = e[i].y;
if (x < y)
add(,y,x,n,x);
else
{
for (int j = y + ; j <= x; j++)
add(,x,y,n,j);
}
}
for (int k = ; k <= n; k++)
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
sum[i][j][k] = sum[i - ][j][k] + sum[i][j - ][k] - sum[i - ][j - ][k] + sum[i][j][k];
} void solve()
{
for (int i = ; i <= n; i++)
{
f[i][i] = ;
f[i][i - ] = ;
}
f[n + ][n] = ;
for (int len = ; len <= n; len++)
for (int i = ; i + len - <= n; i++)
{
int j = i + len - ;
for (int k = i; k <= j; k++)
{
if (sum[i][j][k] == )
{
f[i][j] += f[i][k - ] * f[k + ][j] % mod;
f[i][j] %= mod;
}
}
}
} int main()
{
scanf("%d",&T);
while(T--)
{
memset(sum,,sizeof(sum));
memset(f,,sizeof(f));
flag = true;
scanf("%d%d",&n,&m);
for (ll i = ; i <= m; i++)
{
scanf("%d%d",&e[i].x,&e[i].y);
if (e[i].x == e[i].y)
flag = false;
}
if (!flag)
puts("");
else
{
pre();
solve();
printf("%lld\n",f[][n] % mod);
}
} return ;
}
   

Hdu5181 numbers的更多相关文章

  1. Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range

    在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...

  2. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  3. [LeetCode] Add Two Numbers II 两个数字相加之二

    You are given two linked lists representing two non-negative numbers. The most significant digit com ...

  4. [LeetCode] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字

    Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...

  5. [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  6. [LeetCode] Bitwise AND of Numbers Range 数字范围位相与

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...

  7. [LeetCode] Valid Phone Numbers 验证电话号码

    Given a text file file.txt that contains list of phone numbers (one per line), write a one liner bas ...

  8. [LeetCode] Consecutive Numbers 连续的数字

    Write a SQL query to find all numbers that appear at least three times consecutively. +----+-----+ | ...

  9. [LeetCode] Compare Version Numbers 版本比较

    Compare two version numbers version1 and version1.If version1 > version2 return 1, if version1 &l ...

随机推荐

  1. winform圆角窗体实现

    winform圆角窗体实现 1.窗体的FormBorderStyle设置成None,不要控制边框 2.TransparencyKey和BackColor颜色设置成相同的,这样,窗体就透明了 3.以此为 ...

  2. loadrunner socket协议问题归纳(4)---buffer接收变长和定长的数据

    测试场景:聊天系统 用户登录后,要先向服务器发送用户名,然后可以发送聊天信息,同时也可以接受聊天信息. 如果接受的字符为定长时,可以设定接受长度.recv buf2 66 #include " ...

  3. js 零零散散的总结。

    Array.slice.call(arguments);可以将一个类数组转化为数组. Array.from() ,[...arr];也可以将一个类数组转化为数组(es6). (function() { ...

  4. 我是IT小小鸟(读后感)

    序 1.兴趣,这本书第一个点讲兴趣,可是在中国填鸭式的教育下,有兴趣也被这种教育给泯灭了. 2.他山之石,可以攻玉.但不可照搬.这点我非常赞同作者的看法.别人东西你拿来,一定要在他的基础上进行创   ...

  5. J2EE,J2SE,J2ME,JDK,SDK,JRE,JVM区别(转载)

    转载地址:http://blog.csdn.net/alspwx/article/details/20799017 一.J2EE.J2SE.J2ME区别 J2EE——全称Java 2 Enterpri ...

  6. C#高级编程 (第六版) 学习 第六章:运算符和类型强制转换

    第六章 运算符和类型强制转换 1,运算符 类别 运算符 算术运算符 + - * / % 逻辑运算符 & | ^ ~ && || ! 字符串连接运算符 + 增量和减量运算符 ++ ...

  7. ZOJ 2060 A-Fibonacci Again

    https://vjudge.net/contest/67836#problem/A There are another kind of Fibonacci numbers: F(0) = 7, F( ...

  8. Node.js系列——(3)连接DB

    背景 node.js,有人称之为运行在服务器端的JavaScript.以往我们使用JavaScript时,都是依赖后端查询数据库并返回数据,而JavaScript只需要展示即可.问题来了,就不能绕开后 ...

  9. workstation vmware 制作vm模板

    [root@VM166136 ~]# cat copy_vmware.sh #!/bin/bash if [ $(id -u) -ne 0 ];then echo "Please use t ...

  10. 九度-题目1203:IP地址

    http://ac.jobdu.com/problem.php?pid=1203 题目描述: 输入一个ip地址串,判断是否合法. 输入: 输入的第一行包括一个整数n(1<=n<=500), ...