zoukankan      html  css  js  c++  java
  • HDU2067_小兔的棋盘_catalan_递推

    题目大意: Problem Description 小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧! 解题思路: 看了一下数据,再加上有点感觉是catalan,发现原来是catalan的2倍,嘿嘿,就用catalan大数求了一下。后来看了题解,才发现原来还可以递推,只是,catalan数达到了35的两倍,恐怕__int64也只能刚刚好容下吧,好吧,有些题还真是得试试才知道。 递推代码:
    #include
    using namespace std;
    const int MAX = 36;
    int main(void)
    {
        int n, cas_c = 1;
        __int64 f[MAX][MAX];
        memset(f, 0, sizeof(f));
        f[0][0] = 1;
    
        while(scanf("%d", &n), n >= 0)
        {
            for(int i = 1; i <= n; i++)
            {
                f[i][0] = f[i-1][0];
                for(int j = 1; j < i; j++)
                {
                    f[i][j] = f[i][j-1] + f[i-1][j];
                }
                f[i][i] = f[i][i-1];
            }
            printf("%d %d %I64d\n", cas_c++, n, 2 * f[n][n]);
        }
        return 0;
    }
    
    代码: catalan大数运算:
    //h(n)=h(n-1)*(4*n-2)/(n+1); h(0) = 1;
    #include
    using namespace std;
    const int MAX_LEN = 10005;
    const int MAX_NUM = 36;
    int catalan[MAX_NUM][MAX_LEN];
    
    void multip(int *cata, int b, int &len)
    {
    	int carry = 0;
    	for(int i = 0; i < len; i++)
    	{
    		int temp = cata[i] * b + carry;
    		cata[i] = temp % 10;
    		carry = temp / 10;
    	}
    	while(carry)
    	{
    		len++;
    		cata[len-1] = carry % 10;
    		carry /= 10;
    	}
    	return ;
    }
    
    void division(int *cata, int b, int &len)
    {
    	int r = 0;
    	for(int i = len-1; i >= 0; i--)
    	{
    		int temp = cata[i] + r * 10;
    		cata[i] = temp / b;
    		r = temp % b;
    	}
    	while(!cata[len-1])
    	{
    		len--;
    	}
    	return ;
    }
    
    int main(void)
    {
    	int len[MAX_NUM];
    	memset(catalan, 0, sizeof(catalan));
    	memset(len, 0, sizeof(len));
    	catalan[0][0] = 1;
    	len[0] = 1;
    
    	for(int i = 1; i < MAX_NUM; i++)
    	{
    		memcpy(catalan[i], catalan[i-1], sizeof(catalan[i-1]));
    		len[i] = len[i-1];
    		multip(catalan[i], 4*i-2, len[i]);
    		division(catalan[i], i+1, len[i]);
    	}
    	//for(int i = 0; i < 20; i++)
    	//{
    	//	for(int j = len[i]-1; j >= 0; j--)
    	//	{
    	//		printf("%d", catalan[i][j]);
    	//	}
    	//	printf("\n");
    	//}
    	int n, cas_c = 1;
    	while(scanf("%d", &n), n >= 0)
    	{
    		multip(catalan[n], 2, len[n]);//卡特兰数的两倍
    		printf("%d %d ", cas_c++, n);
    		for(int i = len[n]-1; i >= 0; i--)
    		{
    			printf("%d", catalan[n][i]);
    		}
    		printf("\n");
    	}
    	return 0;
    }
    
  • 相关阅读:
    牛客题霸NC119题解
    牛客题霸NC105题解
    牛客题霸NC93题解
    牛客题霸NC88题解
    牛客题霸NC68题解
    牛客题霸NC45题解
    牛客题霸NC33题解
    牛客题霸NC15题解
    牛客题霸NC04题解
    牛客题霸反转链表题解
  • 原文地址:https://www.cnblogs.com/cchun/p/2520229.html
Copyright © 2011-2022 走看看