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;
    }
    
  • 相关阅读:
    微人事项目-mybatis-持久层
    通过外键连接多个表
    springioc
    Redis 消息中间件 ServiceStack.Redis 轻量级
    深度数据对接 链接服务器 数据传输
    sqlserver 抓取所有执行语句 SQL语句分析 死锁 抓取
    sqlserver 索引优化 CPU占用过高 执行分析 服务器检查
    sql server 远程备份 bak 删除
    冒泡排序
    多线程 异步 beginInvoke EndInvoke 使用
  • 原文地址:https://www.cnblogs.com/cchun/p/2520229.html
Copyright © 2011-2022 走看看