long res = 1;
// here we calculate the total possible path number
// Combination(N, k) = P(N, k)/ k! = n! / (k!(n - k)!)
// reduce the numerator and denominator and get
// C = ( (n - k + 1) * (n - k + 2) * ... * n ) / k!
for (int i = 1; i <= k; ++i) {
//注意,先乘后除,才能保证不会出现精度损失,都能整除!!!
res = res * (N - k + i) / i;
}
经验教训
该类型动态规划题目的两种思路: 把[i,j] 看成是起点还是终点
求解组合问题
代码实现
递归(TLE)
publicintuniquePaths(int m, int n) {
return findPaths(1, 1, m, n);
}
//从[i,j]出发,到[m,n]的共有多少条路径publicintfindPaths(int i, int j, int m, int n) {
if (i == m && j == n) {
return1;
}
if (i > m || j > n) {
return0;
}
//从下方出发与从右方出发的路径和return findPaths(i + 1, j, m, n) + findPaths(i, j + 1, m, n);
}
动态规划
publicintuniquePaths(int m, int n) {
if (m < 0 || n < 0) {
return0;
}
//dp[i][j]:从[i,j]出发,到[m,n]的路径数int[][] dp = newint[m + 1][n + 1];
for (int j = 1; j <= n; ++j) {
dp[m][j] = 1;
}
for (int i = m - 1; i >= 1; --i) {
dp[i][n] = 1;
for (int j = n - 1; j >= 1; --j) {
dp[i][j] = dp[i + 1][j] + dp[i][j + 1];
}
}
return dp[1][1];
}
动态规划空间优化
publicintuniquePaths(int m, int n) {
if (m < 0 || n < 0) {
return0;
}
int[] dp = newint[n + 1];
for (int j = 1; j <= n; ++j) {
dp[j] = 1;
}
for(int i = m - 1; i >= 1; --i) {
dp[n] = 1;
for (int j = n - 1; j >= 1; --j) {
dp[j] = dp[j] + dp[j + 1];
}
}
return dp[1];
}
数学(组合问题)求解
publicintuniquePaths(int m, int n) {
int N = m + n - 2;// how much steps we need to doint k = Math.min(m - 1, n - 1);// number of steps that need to go down or go rightlong res = 1;
// here we calculate the total possible path number // Combination(N, k) = n! / (k!(n - k)!)// reduce the numerator and denominator and get// C = ( (n - k + 1) * (n - k + 2) * ... * n ) / k!for (int i = 1; i <= k; ++i) {
//注意,必须先乘后除,才能保证不会出现精度损失,都能整除
res = res * (N - k + i) / i;
}
//其实当m = 100, n=100时,早就超了,不是很懂这题的测试用例return (int)res;
}