zoukankan      html  css  js  c++  java
  • [小兔的棋盘] 组合数学

    Description

    小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点((0,0))走到终点((n,n))的最短路径数是(C_{2n}^{n}),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧! (n leq 35)

    Solution

    由于规定不能超过对角线,可用分治的思想,只考虑沿对角线分隔开的三角形的情况,对于一个三角形中,求从((0,0))走到终点((n,n))的最短路径,观察发现无论怎么走,设到达某一点时向上走了(i)步,向右走了(j)步,都有(i leq j)这也能通过线性规划相关知识证明。不难发现只是一个类括号匹配问题,可用(Catalan)数求解,计算(C(n))后即是在一个三角形中的解,答案是(2C(n))

    (Catalan)数递推公式 (C(n) = sum_{i=0}^{n-1} C(i) cdot C(n-i-1))
    通项公式(C(n)=frac{C_{2n}^{n}}{n+1})

    预处理(C(n))即可

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <cstring>
    #include <queue>
    typedef long long LL;
    using namespace std;
    LL C[100];
    int main() {
    	C[0] = 1;
    	C[1] = 1;
    	for (int i = 2; i <= 80; i++) {
    		LL t = 0;
    		for (int j = 0; j < i; j++)
    			t += C[j]*C[i - j - 1];
    		C[i] = t;
    	}
    	LL N;
    	int cnt = 1;
    	while (cin >> N) {
    		if (N == -1) break;
    		cout << cnt++ << " " << N << " " << C[N]*2 << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    1282 回文数猜想
    1279 验证角谷猜想
    1205 吃糖果
    1201 18岁生日
    1106 排序
    2024 C语言合法标识符
    196 让气球飞吧
    1001 Sum Problem
    if语句
    三元运算符
  • 原文地址:https://www.cnblogs.com/ez4zzw/p/12452102.html
Copyright © 2011-2022 走看看