目录
一、题目描述
给定m行n列的网格,有一个机器人从左上角(0,0)出发,每一步可以向下或者向右走一步,问有多少种不同的方式走到右下角。
二、思路
动态规划题目类型
1、计数:
有多少种方式走到右下角
有多少种方法选出k个数使得和为Sum
2、求最大最小值:
从左上角走到右下角路径的最大数字和
最长上升子序列长度
3、求存在性:
取石子游戏,先手是否必胜
能不能选出k个数使得和是Sum
本题属于计数型动态规划。
还是动态规划四步走:
1.确定状态
1.1 研究最后一步
因为机器人只能向下或者向右走一步,
所以在走最后一步之前,机器人的位置肯定在右下角的上侧一格或左侧一格。
1.2 化为子问题
机器人从左上角出发,有多少种方法能走到右下角的上侧一格或者左侧一格?
2.转移方程
设f[x][y]为机器人从左上角出发,到达第x行第y列的不同走法之和。
则f[x][y] = f[x-1][y] + f[x][y-1]
备注:加法原理
3.初始条件和边界情况
3.1 初始条件
f[0][0] = 1,机器人只有一种方式从左上角走到左上角3.2 边界情况
x or y 等于0时,机器人只能从一个方向过来,所以:
当x == 0 || y == 0,f[x][y] = 1
4. 计算顺序
一行一行计算,同行则从左至右计算。
三、代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
//1.确定状态
//1.1 研究最后一步
//因为机器人只能向下或者向右走一步,
//所以在走最后一步之前,机器人的位置肯定在右下角的上侧一格或左侧一格。
//1.2 化为子问题
//机器人从左上角出发,有多少种方法能走到右下角的上侧一格或者左侧一格?
//2.转移方程
//设f[x][y]为机器人从左上角出发,到达第x行第y列的不同走法之和。
//则f[x][y] = f[x-1][y] + f[x][y-1]
//备注:加法原理
//3.初始条件和边界情况
//3.1 初始条件
//f[0][0] = 1,机器人只有一种方式从左上角走到左上角
//3.2 边界情况
//x or y 等于0时,机器人只能从一个方向过来,所以:
//当x == 0 || y == 0,f[x][y] = 1
//4. 计算顺序
//一行一行计算,同行则从左至右计算。
//m行n列
int m = 10;
int n = 8;
vector<vector<int>> f(m, vector<int>(n));
for (int x = 0; x < m; x++)
{
for (int y = 0; y < n; y++)
{
if (x == 0 || y == 0)
{
f[x][y] = 1;
}
else
{
f[x][y] = f[x - 1][y] + f[x][y - 1];
}
}
}
cout << f[m - 1][n - 1];
return 0;
}