zoukankan      html  css  js  c++  java
  • 卡特兰数 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
  • 相关阅读:
    第一章:计算机网络参考模型
    阿里云ECS hadoop+spark+zookeeper+hive code-server 集群搭建
    IDEA SSM+MAVEN+JWT 图书管理系统
    IDEA SSM后端框架入门
    code-server Command ' ' not found
    code-server scala error: object apache is not a member of package org
    下面给出一个child-parent的表格,要求挖掘其中的父子辈关系,给出祖孙辈关系的表格。
    现在有多个输入文件,每个文件中的每行内容均为一个整数。要求读取所有文件中的整数,进行升序排序后,输出到一个新的文件中,输出的数据格式为每行两个整数,第一个整数为第二个整数的排序位次,第二个整数为原待排列的整数。
    对于两个输入文件,即文件A 和文件B ,请编写MapReduce程序,对两个文件进行合并排除其中重复的内容,得到一个新的输出文件C。
    现有以下关系型数据库中的表(见表4-20表4-21和表4-22),要求将具转换为适合Hbase存储的表并插入数据。
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8324436.html
Copyright © 2011-2022 走看看