一、什么是递推DP?
这波啊,这波是这波啊,这波是这波啊,这波是这波啊,这波啊,这波是这波啊这波啊,这波是这波啊,这波是······,这波是递推DP。
二、一些例题
1、(70)爬楼梯
需要 n 阶可到达楼顶,每次可爬 1 或 2 个台阶。求爬到楼顶的方法数。
dp[n] = dp[n-1] + dp[n-2];
2、(935)骑士拨号器
国际象棋中的骑士可以按下图所示进行移动:
求可组成的 n 位号码个数 (% 1_000_000_007)。
dp[i] 中保存 n 位号码中末尾位为 i 的个数,相加即代表所有 n 位号码的个数。
用 long 避免溢出。(int 范围 : -2147483648 ~ 2147483647)
public int knightDialer(int n) {
int mod = 1_000_000_007;
long sum = 0;
long[] dp = new long[10];
long[] tmp = new long[10];
Arrays.fill(dp, 1);
if (n == 1) return 10;
for (int i = 2; i <= n; i++) {
tmp[0] = dp[4] + dp[6];
tmp[1] = dp[6] + dp[8];
tmp[2] = dp[7] + dp[9];
tmp[3] = dp[4] + dp[8];
tmp[4] = dp[3] + dp[9] + dp[0]; //此时可能溢出,故用long
tmp[6] = dp[1] + dp[7] + dp[0]; //
tmp[7] = dp[2] + dp[6];
tmp[8] = dp[1] + dp[3];
tmp[9] = dp[2] + dp[4];
for (int j = 0; j < 10; j++) dp[j] = tmp[j] % mod;
}
for (long i : dp) sum = (sum + i) % mod;
return (int) sum;
}