24h購物| | PChome| 登入
2013-06-09 21:18:18| 人氣1,109| 回應0 | 上一篇 | 下一篇

[UVA][math][JAVA] 10643 - Facing Problem With Trees

推薦 0 收藏 0 轉貼0 訂閱站台

 

Facing Problem With Trees
Input: standard input
Output: standard output
Time Limit: 3 seconds


In this problem you are to find the number ( Let P ) of ordered trees where each of the tree consists of exactly m edges and each of the nodes has out-degree either exactly two or zero and the root has even out-degree. For example, if there are four edges, we get the following three trees.

 

Input

 

The first line in the input file is an integer representing the number of test cases. Each of the test cases follows below. Each case consists an integer representing various even values of m ( 2 ≤ m ≤ 500 ).


Output

 

For each test case, first print the serial number of the case and then print the value of P  separated by an space from the serial number. You should use Big Integer operation to print P and P has maximum 200 digits.

 

Sample Input

3

4

10

14

Sample Output

Case 1: 3
Case 2: 126
Case 3: 1716

 


Problem setter: Anupam Bhattacharjee, CSE, BUET

Thanks to Adrian Kuegel for his alternate solution.

"~~ NP ≠ P as NP means never possible and P means possible. Where is my Turing award of 2999?? ~~"







思路很簡單,把卡塔蘭數(Catalan number)抓來使用。
然後 dp[i][j] 表示節點個數 i 個, 根節點具有 j 個分支。

因此 j 一定為偶數,對於卡塔蘭數 F[i] 代表有 2*i+1 個節點(補滿 dummy node)。

那麼可以得到 dp[i][j-2] += dp[i-f1-f2]*F[ff1]*[ff2]

f1 是新增的第一分支的節點個數, F[ff1] 是這個樹的方法數(即卡塔蘭數)
同理 f2, ff2。


import java.util.*;
import java.math.BigInteger;

public class Main {
    static BigInteger[] F = new BigInteger[255];
    static BigInteger[] F2 = new BigInteger[505];
    static BigInteger[][] dp = new BigInteger[505][505];

    public static void main(String[] args) {
        F[0] = BigInteger.ONE;
        for (int i = 1; i < 255; i++) {
            F[i] = F[i - 1].multiply(BigInteger.valueOf(4 * i - 2)).divide(
                    BigInteger.valueOf(i + 1));
        }
        for (int i = 0; i < 505; i++)
            F2[i] = BigInteger.ZERO;
        for (int i = 0; i < 255; i++) {
            for (int j = 0; j < 255; j++) {
                if (i * 2 + 1 + j * 2 + 1 >= 505)
                    break;
                F2[i * 2 + 1 + j * 2 + 1] = F2[i * 2 + 1 + j * 2 + 1].add(F[i]
                        .multiply(F[j]));
            }
        }
        for (int i = 0; i < 505; i++)
            for (int j = 0; j < 505; j++)
                dp[i][j] = BigInteger.ZERO;
        dp[0][0] = BigInteger.valueOf(1);
        dp[1][0] = BigInteger.valueOf(1);
        dp[3][2] = BigInteger.valueOf(1);
        for (int i = 5; i < 505; i += 2) {
            dp[i][2] = F[(i - 1) / 2];
            for (int j = 4; j < i; j += 2) {
                for (int k = 2; k <= i; k += 2) {
                    dp[i][j] = dp[i][j].add(dp[i - k][j - 2].multiply(F2[k]));

                }
            }
        }
        Scanner cin = new Scanner(System.in);
        int testcase = cin.nextInt(), cases = 0;
        while (testcase-- != 0) {
            int n = cin.nextInt();
            BigInteger ret = BigInteger.ZERO;
            for (int i = 2; i <= n; i++)
                ret = ret.add(dp[n + 1][i]);
            System.out.printf("Case %d: %s\n", ++cases, ret);
        }
    }
}

台長: Morris
人氣(1,109) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][math] 10648 - Chocolate Box
此分類上一篇:[UVA][dp] 1347 - Tour

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文