标准二维表问题

问题描述:

设n是一个正整数,2*n的二维表是由正整数1,2,…,2n组成的2*n数组,该数组的每行从左到右递增,每列从上到下递增。这样的数组为标准二维表。
输入一个整数n(0<n<=10^3)
输出标准二维表的个数,由于结果较大,输出结果要模除1000000007。 

输入n

输出一个整数

样例输入

3
样例输出
5

递归的代码:

利用递归时,我们基于入栈和出栈的思想来解决问题:

(1)如果元素出现在第一个位置,则必定是:元素1先入栈、出栈;然后再对其他n-1个元素进行入栈和出栈,如果用h(n)来表示对n个数进行出栈和入栈的次数,则此种情况对应的排列数为h(n-1)。

(2)如果1出现在第二个位置,则此时的状态必然是:元素1和2入栈,元素2出栈,元素1出栈,后面的n-2个元素出入栈。此时的排列数为h(1)h(n-2),此时h(1)代表对元素2出栈和入栈的情况;

(3)如果1出现在第3个位置,则必然是先将1入栈,再后将2、3入栈,再将2、3出栈;然后再将1出栈,最后将其他的n-3个元素进行出栈和入栈。此时的排列数为h(2)h(n-3),其中h(2)代表对2和3两个元素进行入栈和出栈的情况。

......

(4)如果1出现在最后的位置,则必然是1入栈,再后将后面的n-1个数入栈和出栈,最后将1出栈。此时的排列数为h(n-1)。

基于加法原则,对n个元素进行出栈和入栈的排列情况数为:

h(n)=h(n-1)+h(1)h(n-2)+...+h(n-1)

如果规定h(0)=1,则第一种情况h(n-1)可以写为h(0)h(n-1)。因此如果假设完成n次出栈和入栈的次数为h(n),则有

h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)

其中初始条件为h(0)=1。

还要考虑输出结果不要整形溢出,所以:下面的代码

#include<stdio.h>
long long NumST[10000];
void PER()
{
    int i,j;
    NumST[0]=1;
    long long sumCount;
    for(i=1;i<1001;i++)
    {
        sumCount=0;
        for(j=0;j<i;j++)
        {
            sumCount+=NumST[j]*NumST[i-1-j];
            sumCount=sumCount%1000000007;   
        }
        NumST[i]=sumCount;
    }
}
 
 
int main()
{
    int n;
    scanf("%d",&n);
    PER();
    printf("%lld",NumST[n]);
    return 0;
}

暴力搜索的代码:

运用暴力搜索时,我们基于任意时刻0的个数比1多的原理(总的0的个数是与1相等的),将这2n个数字的位置设定为在上面就是0,在下边就是1,构造一个二进制字符串来表示这些数字的位置情况,将每一种情况下的结果保存进一个数组,统计数组中0和1的个数,进行判断,即可。

#include <stdio.h>
#include <math.h>
 
int judge(int a[], int n){
//判断字符串是否符合条件,0和1的个数相同,任意时刻0的个数比1应多
    int sum0, sum1;
    int i;
    sum0=sum1=0;
 
    for(i=0;i<n;i++){
        if(a[i]==0) sum0++;
        else sum1++;
 
        if(sum0<sum1)
            return 0;
    }
 
    if(sum0!=sum1)
        return 0;
    return 1;
}
 
int main()
{
    int n,i,count=0;
    int *table;
    int num,temp;
 
    scanf("%d",&n);
    table= new int[2*n-1];
 
    for(num=0;num<(int)pow(2.,2*n);num++){
        temp=num;
        for(i=0;i<2*n;i++){
            table[i]=temp%2;
            temp/=2;
        }
 
        if(judge(table,2*n)){
            count++;
        }
    }
 
    printf("%d\n",count);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/cqwoniu/article/details/84201606
今日推荐