• 卡特兰数 HDU2067 & HDU4165 & HDU1134


    题目链接:https://vjudge.net/problem/HDU-2067

    小兔的棋盘

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 11800    Accepted Submission(s): 5952

    Problem Description
    小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!
     
    Input
    每次输入一个数n(1<=n<=35),当n等于-1时结束输入。
     
    Output
    对于每个输入数据输出路径数,具体格式看Sample。
     
    Sample Input
    1 3 12 -1
     
    Sample Output
    1 1 2 2 3 10 3 12 416024
     
    Author
    Rabbit
     
    Source
     
    Recommend
    lcy

    题解:

    卡特兰数的初步学习卡特兰数应用

    2.卡特兰数计算公式:

     1) h(n) = h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0) (n>=1) , 其中 h[0] = 1;

     2) h(n) = c(2n,n) - c(2n,n+1)(n=0,1,2,...) <==> h(n) = C(2n,n)/(n+1)

     3) h(n) = h(n-1)*(4*n-2) / (i+1)  ……此条计算公式容易溢出

    注意:卡特兰数的计算很容易溢出。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 using namespace std;
    13 typedef long long LL;
    14 const int INF = 2e9;
    15 const LL LNF = 9e18;
    16 const int MOD = 1e9+7;
    17 const int MAXN = 35+10;
    18 
    19 LL h[MAXN];
    20 
    21 void init()
    22 {
    23     memset(h, 0, sizeof(h));
    24     h[0] = 1; h[1] = 1;
    25     for(int i = 2; i<MAXN; i++)
    26         for(int j = 0; j<i; j++)
    27             h[i] += 1LL*h[j]*h[i-j-1];
    28 }
    29 
    30 int main()
    31 {
    32     init();
    33     int kase = 0, n;
    34     while(scanf("%d", &n) && n!=-1)
    35         printf("%d %d %lld
    ", ++kase, n, 2LL*h[n]);
    36 }
    View Code

    题目链接: https://vjudge.net/problem/HDU-4165

    Pills

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1626    Accepted Submission(s): 1139

    Problem Description
    Aunt Lizzie takes half a pill of a certain medicine every day. She starts with a bottle that contains N pills.

    On the first day, she removes a random pill, breaks it in two halves, takes one half and puts the other half back into the bottle.

    On subsequent days, she removes a random piece (which can be either a whole pill or half a pill) from the bottle. If it is half a pill, she takes it. If it is a whole pill, she takes one half and puts the other half back into the bottle.

    In how many ways can she empty the bottle? We represent the sequence of pills removed from the bottle in the course of 2N days as a string, where the i-th character is W if a whole pill was chosen on the i-th day, and H if a half pill was chosen (0 <= i < 2N). How many different valid strings are there that empty the bottle?
     
    Input
    The input will contain data for at most 1000 problem instances. For each problem instance there will be one line of input: a positive integer N <= 30, the number of pills initially in the bottle. End of input will be indicated by 0.
     
    Output
    For each problem instance, the output will be a single number, displayed at the beginning of a new line. It will be the number of different ways the bottle can be emptied.
     
    Sample Input
    6 1 4 2 3 30 0
     
    Sample Output
    132 1 14 2 5 3814986502092304
     
    Source
    Recommend
    lcy

    题解:

    有n片药,每天吃半片。当天要么在药罐中抽到把一片完整的药片,然后分成两半,吃一半,最后把另一半放回药罐中;要么抽到半片药片直接吃。问:有多少种情况? 单纯的卡特兰数。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 using namespace std;
    13 typedef long long LL;
    14 const int INF = 2e9;
    15 const LL LNF = 9e18;
    16 const int MOD = 1e9+7;
    17 const int MAXN = 30+10;
    18 
    19 LL h[MAXN];
    20 
    21 void init()
    22 {
    23     memset(h, 0, sizeof(h));
    24     h[0] = 1;
    25     for(int i = 1; i<MAXN; i++)
    26         for(int j = 0; j<i; j++)
    27             h[i] += 1LL*h[j]*h[i-j-1];
    28 }
    29 
    30 int main()
    31 {
    32     init();
    33     int n;
    34     while(scanf("%d", &n) && n)
    35         printf("%lld
    ", h[n]);
    36 }
    View Code

    题目链接:https://vjudge.net/problem/HDU-1134

    Game of Connections

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 5112    Accepted Submission(s): 2934

    Problem Description
    This is a small but ancient game. You are supposed to write down the numbers 1, 2, 3, ... , 2n - 1, 2n consecutively in clockwise order on the ground to form a circle, and then, to draw some straight line segments to connect them into number pairs. Every number must be connected to exactly one another. And, no two segments are allowed to intersect.

    It's still a simple game, isn't it? But after you've written down the 2n numbers, can you tell me in how many different ways can you connect the numbers into pairs? Life is harder, right?
     
    Input
    Each line of the input file will be a single positive number n, except the last line, which is a number -1. You may assume that 1 <= n <= 100.
     
    Output
    For each n, print in a single line the number of ways to connect the 2n numbers into pairs.
     
    Sample Input
    2 3 -1
    Sample Output
    2 5
    Source
     
    Recommend
    Eddy

    题意:

    1~2*n 顺时针排列成一圈, 用n条线段连接n对数,要求线段不能有交叉,问:有多少种连接情况?

    题解:

    可以将此题联想到出栈问题,这样就转化成卡特兰数了。

    递推式一:

     1 import java.util.Scanner;
     2 import java.math.BigInteger;
     3 
     4 public class Main {
     5     
     6     public static void main(String[] args){
     7         
     8         BigInteger[] a = new BigInteger[105];
     9         
    10         a[0] = BigInteger.ONE;
    11         for(int i=1; i<=100; i++) {
    12             a[i] = BigInteger.valueOf(0); 
    13             for(int j=0;j<i;j++){
    14                 a[i] = a[i].add(a[j].multiply(a[i-j-1]));
    15             }
    16         }
    17             
    18         Scanner input = new Scanner(System.in);
    19         while(input.hasNext()){
    20             int n=input.nextInt();
    21             if(n==-1) break;
    22             System.out.println(a[n]);
    23         }
    24     }
    25 }
    View Code

    递推式二:

     1 import java.util.Scanner;
     2 import java.math.BigInteger;
     3 
     4 public class Main {
     5     
     6     public static void main(String[] args){
     7         
     8         BigInteger[] a = new BigInteger[105];
     9         
    10         a[0] = BigInteger.ONE;
    11         for(int i=1; i<=100; i++) {
    12             a[i] = a[i-1].multiply(BigInteger.valueOf(4*i-2)).divide(BigInteger.valueOf(i+1));
    13         }
    14             
    15         Scanner input = new Scanner(System.in);
    16         while(input.hasNext()){
    17             int n=input.nextInt();
    18             if(n==-1) break;
    19             System.out.println(a[n]);
    20         }
    21     }
    22 }
    View Code
  • 相关阅读:
    monkey之monkey日志分析
    ros 阅读记录 1
    Occupancy Grid Maps 资料记录
    双目稠密点云的资料记录
    ros 在callback中publish (不用类的方法)
    ros中同时订阅两个topic(2张图像)合并成一个topic(1张图像)
    编译 链接和加载 (转)
    制作自己的livecd
    源码安装ROS Melodic Python3 指南 (转) + 安装记录
    Depth from Videos in the Wild 解读
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8324436.html
Copyright © 2020-2023  润新知