思路: ①dp ②卡特兰数
①:画图,取右下三角形分析,每次都只能向右或向上走。如图所示:
说明:蓝色是初始化, 黑色是行列号,紫色是 该点=左点+下点
所以状态转移方程为 dp[i][j] = dp[i][j-1] + dp[i+1][j];
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long dp[40][40];
int main() {
int n, cnt = 1;
while(~scanf("%d", &n) && n != -1) {
memset(dp, 0, sizeof(dp));//初始化
for(int j = 1; j <= n+1; j++) //初始化
dp[n+1][j] = 1;
for(int i = n; i >= 1; i--) {
for(int j = n+2-i; j <= n+1; j++) {
dp[i][j] = dp[i+1][j] + dp[i][j-1];
}
}
printf("%d %d %lld
", cnt++, n, dp[1][n+1]*2);//2倍 爆int
}
}
②:卡特兰数
卡特兰数经典例子:扫描01串,任意位置 保证经过1的个数大于等于0的个数。还有左右括号,进栈出栈问题,这里转化为卡特兰数是因为说了不能越过对角线,暗含的意思就是任意位置,向右走的得大于等于向上走的。
AC代码:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static BigInteger catalans[] = new BigInteger[10010];//开数组
static BigInteger four = new BigInteger("4");//好用
static BigInteger tow = new BigInteger("2");
static BigInteger one = new BigInteger("1");
public static void init() {//初始化函数
catalans[1] = new BigInteger("1");
for(int i = 2; i < 10010; i++) {//这里真的酷!
catalans[i] = catalans[i-1].multiply(four.multiply(BigInteger.valueOf(i)).subtract(two)).divide(BigInteger.valueOf(i+1));
}
}
public static void main(String[] args) {
init();
Scanner scanner = new Scanner(System.in);//输入处理
while(scanner.hasNext()) {
int n = scanner.nextInt();
//输出也好用
System.out.println(catalans[n].divideAndRemainder(new BigInteger("1000000007"))[1]);
}
}
}
看到了这位大佬的博客,燃起了我心中的Java 链接
第一个AC的Java代码,心得:
下载编译器,JDK,(汉化包没弄好),知道了如何编写,提交的时候要改成Main,不要package。
以后大数就用JAVA了。