题目
我们可以把棋盘的左下角看做二维坐标的原点(0,0),把棋盘的右上角看做二维坐标(M,N)(坐标系的单位长度为小方格的变长)
思路
用f(i,j)表示移动到坐标f(i,j)的走法总数,其中0= f(m,n)=f(m-1,n)+f(m,n-1).
于是状态f(i,j)的状态转移方程为:
f(i,j)=f(i-1,j)+f(i,j-1) if i,j>0
f(i,j)=f(i,j-1) if i=0
f(i,j)=f(i-1,j) if j=0
初始情况就为:f(0,0)=0, f(0,1)=1, f(1,0)=1,这个问题可以在时间O(n^2) 内求解,非递归解.
代码
/*非递归解法*/
int processNew(int m,int n){
vector> Q(m+1,vector (n+1,0));
//初始化
for(int j=1; j<=n; ++j)
Q[0][j]=1;
for(int i=1; i<=m; ++i)
Q[i][0]=1;
//迭代计算
for(int i=1; i<=m; ++i){
for(int j=1; j<=n; ++j){
Q[i][j]=Q[i-1][j]+Q[i][j-1];
}
}
int res=Q[m][n];
return res;
}
/递归解法
int process(int m, int n) {
/*if (m == 0 && n == 0) 我觉得这部分不要
return 0;*/
if (m==0 || n==0)
return 1;
return process(m, n - 1) + process(m - 1, n);
题目
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
例如,上图是一个7 x 3 的网格。有多少可能的路径?
说明:m 和 n 的值均不超过 100。
代码
class Solution {
public:
int uniquePaths(int m, int n) {
vector> dp(m+1,vector (n+1,0));
dp[1][1]=1; //可以初始化dp[1][0]=1或者dp[0][1]=1;更方便
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
if(i==1 && j==1)
continue;
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
return dp[m][n];
}
};
/*
class Solution {
public:
int uniquePaths(int m, int n) {
vector> dp(m+1,vector (n+1,0));
dp[1][0]=1;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
dp[i][j]=dp[i-1][j]+dp[i][j-1];
return dp[m][n];
}
};
*/
题目
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
说明:m 和 n 的值均不超过 100。
示例 1:
输入:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
输出: 2
代码
class Solution {
public:
int uniquePathsWithObstacles(vector>& obstacleGrid) {
int m=obstacleGrid.size();
int n=obstacleGrid[0].size();
vector> dp(m+1,vector (n+1,0));
dp[1][0]=1; //不用在起点开始,这里是重点
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
{
if(obstacleGrid[i-1][j-1]==1)
continue;
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
return dp[m][n];
}
};
题目
思路
86的矩阵,从左下角A到右上角B,一共需要走12步,其中5步向上,7步向右,因此总的走法一共有C(12,5)=792种,但题目规定不能经过P,因此需要减去经过P点的走法。
经过P的路径分为两部分,从A到P,从P到B。
同理,从A到P的走法:C(6,2)=15;
同理,从P到B的走法:C(6,3)=20;
因此从A到B经过P点的走法有1520=300种,
所以从A到B不经过P点的走法有792-300=492种。这题其实可以用程序算出来
简单的动态规划dp[i][j] = dp[i][j-1] + dp[i-1][j];
代码**
#include
using namespace std;
int main()
{
int dp[7][9] = {0};
dp[1][0]=1;
for(int i = 1; i <= 6; i++)
for(int j = 1; j <= 8; j++)
dp[i][j] = dp[i-1][j] + dp[i][j-1];
cout<
此类题目还有:A点到B点的最短路径,那么只需要比较dp[i-1][j] 和 dp[i][j-1]哪个小了