2014-03-20 02:55
题目:从(0, 0)走到(x, y),其中x、y都是非负整数。每次只能向x或y轴的正方向走一格,那么总共有多少种走法。如果有些地方被障碍挡住不能走呢?
解法1:如果没有障碍的话,组合数学,排列组合公式C(x + y, x)。
代码:
1 // 9.2 How many ways are there to go from (0, 0) to (x, y), if you only go left or up, and one unit at a time? 2 #include <cstdio> 3 using namespace std; 4 5 int combination(int n, int k) 6 { 7 if (n < k) { 8 return 0; 9 } else if (n == 0) { 10 return 0; 11 } else if (k > n / 2) { 12 return combination(n, n - k); 13 } 14 15 int i; 16 int res, div; 17 18 res = div = 1; 19 for (i = 1; i <= k; ++i) { 20 res *= (n + 1 - i); 21 div *= i; 22 if (res % div == 0) { 23 res /= div; 24 div = 1; 25 } 26 } 27 if (res % div == 0) { 28 res /= div; 29 div = 1; 30 } 31 32 return res; 33 } 34 35 int main() 36 { 37 int x, y; 38 39 while (scanf("%d%d", &x, &y) == 2 && x >= 0 && y >= 0) { 40 printf("%d ", combination(x + y, x)); 41 } 42 43 return 0; 44 }
解法2:如果有障碍的话,用动态规划。
代码:
1 // 9.2 How many ways are there to go from (0, 0) to (x, y), if you only go left or up, and one unit at a time? 2 // If some of the positions are off limits, what would you do? 3 #include <cstdio> 4 #include <vector> 5 using namespace std; 6 7 int main() 8 { 9 int x, y; 10 int i, j; 11 vector<vector<int> > off_limits; 12 vector<vector<int> > res; 13 14 while (scanf("%d%d", &x, &y) == 2 && x >= 0 && y >= 0) { 15 ++x; 16 ++y; 17 off_limits.resize(x); 18 res.resize(x); 19 for (i = 0; i < x; ++i) { 20 off_limits[i].resize(y); 21 res[i].resize(y); 22 } 23 for (i = 0; i < x; ++i) { 24 for (j = 0; j < y; ++j) { 25 scanf("%d", &off_limits[i][j]); 26 off_limits[i][j] = !!off_limits[i][j]; 27 res[i][j] = 0; 28 } 29 } 30 31 res[0][0] = off_limits[0][0] ? 0 : 1; 32 for (i = 1; i < x; ++i) { 33 res[i][0] = off_limits[i][0] ? 0 : res[i - 1][0]; 34 } 35 for (j = 1; j < y; ++j) { 36 res[0][j] = off_limits[0][j] ? 0 : res[0][j - 1]; 37 } 38 for (i = 1; i < x; ++i) { 39 for (j = 1; j < y; ++j) { 40 res[i][j] = off_limits[i][j] ? 0 : res[i - 1][j] + res[i][j - 1]; 41 } 42 } 43 44 for (i = 0; i < x; ++i) { 45 for (j = 0; j < y; ++j) { 46 printf("%d ", res[i][j]); 47 } 48 printf(" "); 49 } 50 printf("%d ", res[x - 1][y - 1]); 51 52 for (i = 0; i < x; ++i) { 53 off_limits[i].clear(); 54 res[i].clear(); 55 } 56 off_limits.clear(); 57 res.clear(); 58 } 59 60 return 0; 61 }