zoukankan      html  css  js  c++  java
  • Hdoj 5181 numbers

    numbers

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


    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({10}^{9}+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 leq n leq 300) and m(1 leq m leq 90000).
    Next m lines contains two integers A and B(1 leq A leq n,1 leq B leq 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




    设f[i][j]为数字(i-j)的出栈方案数,显然我们可以枚举最后一个出栈的元素k,i<=k<=j。先把[i,k-1]出栈完了之后,把k放进去,然后再放[k+1,j]
    并且出栈后再出k。
    所以我们可以得到递推式 f[i][j]=
    Σf[i][k-1]*f[k+1][j] ,当然因为有限制这里的k显然不能取区间[i,j]的所有数。

    当然A,B只能对 L<=min(A,B),R>=max(A,B)的f[L][R]产生影响。
    我们发现当A<B时,只要k!=A就是合法的,因为出栈顺序是[i,k-1]->[k+1,j]->k;
    而当A>B时,观察出栈顺序也可以发现只要k¢(B,A]就是合法的。

    于是现在的问题变成了如何快速判断一个k在对于f[i][j]是否合法。。。。
    我们可以发现的是,当把区间的左端点看成横坐标,区间的右端点看成纵坐标的时候,对于一组A、B
    不合法的区域就是以(1,max(A,B))为左下角,(min(A,B),n)为右上角的矩形。
    虽然这个坐标系只有在直线y=x上方的区域是有用的,但是我们不妨对每个k都做一遍差分,
    然后再前缀和一下得到它在哪些区间是不合法的。
    这样就可以 O(N^3 + N*M) 完成本题了。

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int ha=1000000007;
    int f[305][305],n,m,T;
    int uu,vv,ban[305][305][305];
    bool flag;
    
    inline int add(int x,int y){
    	x+=y;
    	return x>=ha?x-ha:x;
    }
    
    inline void init(){
    	memset(f,0,sizeof(f));
    	memset(ban,0,sizeof(ban));
    	flag=0;
    }
    
    inline void matrix(int px1,int py1,int px2,int py2,int num){
    	ban[num][px1][py1]++;
    	ban[num][px2+1][py1]--;
    	ban[num][px1][py2+1]--;
    	ban[num][px2+1][py2+1]++;
    }
    
    inline void dp(){
    	for(int i=1;i<=n;i++)
    	    for(int j=1;j<=n;j++)
    	        for(int k=1;k<=n;k++) ban[i][j][k]+=ban[i][j-1][k]+ban[i][j][k-1]-ban[i][j-1][k-1];
    	
    	for(int i=1;i<=n;i++) f[i][i]=f[i][i-1]=1;
    	f[n+1][n]=1;
    	
    	for(int len=1;len<n;len++)
    	    for(int i=1,j;(j=i+len)<=n;i++)
    	        for(int k=i;k<=j;k++) if(!ban[k][i][j]){
    	        	f[i][j]=add(f[i][j],f[i][k-1]*(ll)f[k+1][j]%ha);
    			}
    }
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		init();
    		scanf("%d%d",&n,&m);
    		while(m--){
    			scanf("%d%d",&uu,&vv);
    			if(uu<vv){
    				matrix(1,vv,uu,n,uu);
    			}
    			else if(uu>vv){
    				for(int j=vv+1;j<=uu;j++) matrix(1,uu,vv,n,j);
    			}
    			else flag=1;
    		}
    		
    		
    		if(flag){
    			puts("0");
    			continue;
    		}
    		
    		
    		dp();
    		
    		printf("%d
    ",f[1][n]);
    	}
    	
    	return 0;
    }
    
    
    

      


  • 相关阅读:
    LeetCode Path Sum II
    LeetCode Longest Palindromic Substring
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Best Time to Buy and Sell Stock III
    LeetCode Binary Tree Maximum Path Sum
    LeetCode Find Peak Element
    LeetCode Maximum Product Subarray
    LeetCode Intersection of Two Linked Lists
    一天一个设计模式(1)——工厂模式
    PHP迭代器 Iterator
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8503789.html
Copyright © 2011-2022 走看看