给定两个正整数int x,int y,代表一个x乘y的网格,现有一个机器人要从网格左上角顶点走到右下角,每次只能走一步且只能向右或向下走,返回机器人有多少种走法。保证x+y小于等于12。
测试样例:
2,2
返回:2
/*基本动态规划*/
public int countWays(int x, int y) {
// write code here
int[][] dp = new int[x][y];
dp[0][0] = 1;
for(int i = 1; i < x; i++){
dp[i][0] = dp[i-1][0];
}
for(int i = 1; i < y; i++){
dp[0][i] = dp[0][i-1];
}
for(int i = 1; i < x; i++){
for(int j = 1; j < y; j++){
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[x-1][y-1];
}
// 题目要求走的是大格子而不是网格线的交点,所以有两种走法。
// 二维数组用于计算走到当前格子的走法总数,为其上方格子走法总数与其左侧格子走法总数之和
public int countWays(int x, int y) {
// write code here
int[][] dp = new int[13][13];
for (int i = 1; i < y; i++)
dp[0][i] = 1;
for (int i = 1; i < x; i++)
dp[i][0] = 1;
for (int i = 1; i < x; i++)
for (int j = 1; j < y; j++)
dp[i][j] = dp[i-1][j] + dp[i][j-1];
return dp[x-1][y-1];
}
class Robot {
public:
int countWays(int x, int y) {
// write code here
return factorial(y,x+y-2)/factorial(1,x-1);
}
int factorial(int f,int t){
int res=1;
for(int i=f;i<=t;i++){
res = res*i;
}
return res;
}
};
public class Robot {
public int countWays(int x, int y) {
if ( x==1 || y==1 )
return 1;
return countWays(x-1,y)+countWays(x,y-1);
}
}
class Robot {
public:
int countWays(int x, int y) {
// write code ,here
int dp[13][13]={0};
dp[0][0]=0;
for(int i=1;i<y;i++)//第一行初始化,因为只有横着走一种方法。
dp[0][i]=1;
for(int i=1;i<x;i++)//第一列初始化,因为只有竖着一种方法。
dp[i][0]=1;
for(int i=1;i<x;i++)//dp[i][j]的方法,等于走到上面一格和走到左边一个方法之和。
for(int j=1;j<y;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
return dp[x-1][y-1];
}
};
}
/*
递归解法详解:
countWays(int x, int y)表示当前的格子为x*y
因此我们有两种终止条件和一个递归条件
当x==0||y==0表示该表格不存在,走法为0
当x==1||y==1表示该表格为 x*1 或 1*y,那么走到终点只有一种方法
剩下的情况则由递归条件操作,
当前的走法 = 他的上一格走法 + 他左边格子的走法
*/
public class Robot {
public int countWays(int x, int y) {
// write code here
if(x==0||y==0)return 0;
if(x==1||y==1)return 1;
return countWays(x-1,y) + countWays(x,y-1);
}
} | 0 | 1 | 1 | 1 | 1 | 1 |
| 1 | | | | | |
| 1 | | | | | |
| 1 | | | | | |
| 1 | | | | | E |
class Robot {
public:
int countWays(int x, int y) {
int dp[x][y];
dp[0][0] = 0;
for (int i = 1; i < x; ++i) {
dp[i][0] = 1;
}
for (int i = 1; i < y; ++i) {
dp[0][i] = 1;
}
for (int r = 1; r < x; ++r) {
for (int c = 1; c < y; ++c) {
dp[r][c] = dp[r-1][c] + dp[r][c-1];
}
}
return dp[x-1][y-1];
}
}; class Robot {
public:
int countWays(int x, int y) {
// write code here
int* pDP = new int[y];
for (int i = 0; i < y; ++i)
pDP[i] = 1;
for (int i = 1; i < x; ++i)
for (int j = 1; j < y; ++j)
pDP[j] = pDP[j - 1] + pDP[j];
int nRes = pDP[y - 1];
delete[] pDP;
return nRes;
}
}; class Robot {
public:
int countWays(int x, int y) {
// write code here
int dp[x][y];
for (int i = 0; i < x; ++i)
for (int j = 0; j < y; ++j) {
dp[i][j] = 0;
}
dp[0][1] = 1;dp[1][0] = 1;
for (int i = 0; i < x; ++i) {
for (int j = 0; j < y; ++j) {
if(i - 1 >= 0) dp[i][j] += dp[i-1][j];
if(j - 1 >= 0) dp[i][j] += dp[i][j-1];
}
}
return dp[x-1][y-1];
}
};
class Robot {
public:
int countWays(int x, int y) {
int F[20][20]{0};
for (int i=1; i<x; ++i) {
F[i][0] = 1;
}
for (int i=1; i<y; ++i) {
F[0][i] = 1;
}
for (int i=1; i<x; ++i) {
for (int j=1; j<y; ++j) {
F[i][j] = F[i-1][j] + F[i][j-1];
}
}
return F[x-1][y-1];
}
};
运行时间:3ms
占用内存:460k
class Robot {
public:
int countWays(int x, int y) {
// write code here
int dp[y];
for(int i = 0; i < y; i++)
dp[i] = 1;
for(int i = 1; i < x; i++){
for(int j = 1; j< y; j++){
dp[j] = dp[j] + dp[j-1];
}
}
return dp[y-1];
}
};
由于题目中x+y<=12,所以不必担心递归超时问题,对于每一步,只要没有走到 边缘(x==1||y==1)就会有两种选择:向下走(x-1)or 向右走(y-1),终 止条件即走到边缘,只能一直走下去,即此时只有一种走法。 class Robot { public: int countWays(int x, int y) { // write code here if(x<=0||y<=0) return 0; if(x==1||y==1) return 1; return countWays(x-1,y)+countWays(x,y-1); } };