HDU 1023 Train Problem II 、CSU 1320 Scoop water(卡特兰数练习)

A - Scoop water

Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu

Submit Status

Description

  zzy今天刚买了两个水瓢A和B,容量都是为1升,童心未泯的他打算用这个水瓢来玩游戏。

  首先zzy准备了一个容量可看作无穷大的水缸,刚开始水缸是空的,然后用水瓢A往水缸里加水,用水瓢B把水缸里的水舀出去,当使用 水瓢B把水舀出去时水缸里必须要至少有1升的水。这样子使用N次水瓢A,也使用N次水瓢B,最后水缸会依旧空的。

Input

  输入有多个例子,直到文件结束。

  每个例子仅含一个数N(0<N<=10000),表示你必须使用N次A水瓢和N次B水瓢。

Output

  对于每个例子,请输出一个数,表示一共有多少种正确的舀水方式使得舀水过程中 使用B水瓢时水缸里总会有足够的水。

 (由于数字比较大,输出的答案模1000000007)

Sample Input

1
2

Sample Output

1
2

思路:有木有觉得这个舀水倒水的过程很像栈,像是栈的进进出出,求组合总数也就是求栈的方式总数,那就是使用卡特兰数公式了,p[n]=p[n-1]*p[0]+p[n-2]*p[1]+......+p[0]*p[n-1]。或者p[n]=p[n-1]*(4*n-2)/n+1;

第一次写时采用的是第二个公式,但是long long会溢出,溢出在取余前(应该是那个*(4n-2)的原因),所以应该采用第一个公式,每乘2个数就取余,将余数相加,就避免了溢出。而且第一个公式也是匹配递推dp思想的。为什么与栈扯上关系?请了解

卡特兰数的性质与应用:https://blog.csdn.net/qq_26010491/article/details/50363804

代码如下:

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<string>
using namespace std;
long long int p[10005];
void katelanshu()
{
	int i,j;
	p[0]=1;
	for(i=1;i<=10000;i++)
	{
		for(j=0;j<i;j++)
		{
			p[i]+=p[j]*p[i-j-1];
			p[i]=p[i]%1000000007;//每加一次就取余一次,余数累加。不能使用p[n]=p[n-1]*(4*n-2)/(n+1) ,在乘的过程中数据会溢出 
		}
	}
} 
int main()
{
    int n,i,j;
    katelanshu();
	while(scanf("%d",&n)!=EOF)
	{
		printf("%lld\n",p[n]);
	}
	return 0;
}

Train Problem II

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

As we all know the Train Problem I, the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order, how many orders that all the trains can get out of the railway.

Input

The input contains several test cases. Each test cases consists of a number N(1<=N<=100). The input is terminated by the end of file.

Output

For each test case, you should output how many ways that all the trains can get out of the railway.

Sample Input

1

2

3

10

Sample Output

1

2

5

16796

Hint

 The result will be very large, so you may not process it by 32-bit integers. 

题目大意:火车先进后出,求种数。

思路:火车。。。还是求栈数问题,卡特兰数问题,上公式,不用考虑那么多,大数,,,善意的提醒这道题需要使用大数,不然数据会炸掉,没有去余数据又大,必须用大数。

代码如下:

#include<iostream>
using namespace std;
int a[105][100];
void katelan()
{
    int i,j,k,m;
    a[2][0]=1;a[2][1]=2;
    a[1][0]=1;a[1][1]=1;
    m=1;
    for(i=3;i<101;i++)
    {
        k=0;
        for(j=1;j<=m;j++)
        {
            int t=(a[i-1][j])*(4*i-2)+k;//使用另类递推公式p[n]=p[n-1]*(4*n-2)/m+1; 
            k=t/10;
            a[i][j]=t%10;
        }
        while(k!=0)
        {
            a[i][++m]=k%10;
            k/=10;
        }
        for(j=m;j>=1;j--)
        {
            int t=a[i][j]+k*10;
            a[i][j]=t/(i+1);
            k=t%(i+1);
        }
        while(a[i][m]==0)
        {
            m--;
        }
        a[i][0]=m;//保存位数 
    }
}
int main()
{
    katelan();
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=a[n][0];i>0;i--)
        {
            printf("%d",a[n][i]);
        }
        puts("");
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/pleasantly1/article/details/81094438
今日推荐