题意:
从坐标(0, 0)到(n, 0)的折线,这条折线每向右延伸一个单位长度,高度要么不变,要么+1,要么-1,(不能到y=0以下)已知n,求这种折线种数。
思路:
想要从(0,0)到(n,0),说明此过程中必定要向上向下的次数相同,且限制不能下降到y轴下,所以正好满足卡特兰数的入栈出栈性质,于是问题就转换成了从n次中选择2*k次进行向上向下。不过直接去用大数进行运算会超时,即预处理大数组合数1e5的运算会超时。。。已知ans[k] = C(n, 2*k) * C(2*k, k)/(k+1),另ans[k]除以ans[k-1]得递推公式:ans[k] = ans[k] * (n-2*k+2) * (n-2*k+1) / (k*(k+1))。
代码:
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static int maxn = 10005;
static BigInteger f[] = new BigInteger[maxn];
static BigDecimal mod1 = new BigDecimal("1E+100");
static BigInteger mod = mod1.toBigInteger();
static BigInteger ans, tmp;
static int n, up;
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
n = cin.nextInt();
ans = BigInteger.ONE;
tmp = BigInteger.ONE;
up = n/2;
for(int i = 1; i <= up; ++i) {
tmp = tmp.multiply(BigInteger.valueOf(n-2*i+2))
.multiply(BigInteger.valueOf(n-2*i+1))
.divide(BigInteger.valueOf(i*(i+1)));
ans = ans.add(tmp);
}
System.out.println(ans.mod(mod));
}
}
}
继续加油~