题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2604
解题思路:
用dp[n][k]表示长度为2n深度不超过k的括号序列个数,那么答案就是dp[n][k]-dp[n][k-1]。
- 边界条件:dp[0][j] = 1
- 递推公式:dp[i][j] = sum{dp[i-k][j] * dp[k-1][j-1] | 0<k≤i}
dp[i][j] = sum{dp[i-k][j] * dp[k-1][j-1] | 0<k≤i}
i对括号深度不超过j的,可以唯一表示为(X)Y形式,其中X和Y可以为空,设X有k-1对括号,则对应的方案数为dp[i-k][j] * dp[k-1][j-1]
AC代码:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static BigInteger dp[][] = new BigInteger[55][55];
public static void init(){
for(int i =0; i <= 50; i++)
for(int j = 0; j <= 50; j++)
dp[i][j] = BigInteger.ZERO;
for(int j = 0; j <= 50; j++)
dp[0][j] = BigInteger.ONE;
for(int i = 1; i <= 50; i++)
for(int j =1; j <= 50; j++)
for(int k = 1; k <= i; k++)
dp[i][j] = dp[i][j].add(dp[i-k][j].multiply(dp[k-1][j-1]));
}
public static void main(String[] args) {
init();
Scanner sca = new Scanner(System.in);
int t = 1;
while(sca.hasNext()){
int n = sca.nextInt();
int k = sca.nextInt();
if(n + k == 0)
break;
BigInteger sum = BigInteger.ONE;
if(t > 1)
System.out.println("");
System.out.printf("Case %d: ", t++);
System.out.println(dp[n][k].subtract(dp[n][k-1]));
}
}
}