动态规划的三大步骤
- 定义数组的含义
用一个数组,来保存历史数组。
dp[]:规定这个数组元素的含义 - 找出数组元素之间的关系式 利用归纳法,对历史数据来退出新的元素值,找出数组元素之间的关系式。
- 找出初始值 利用第二步骤中推出的数组元素之间的关系,分解到不能再分解为止,找到初始值。
斐波那契数列
斐波那契数列的边界条件是F(0)=0和F(1) = 1,
例子
二维数组的DP
问题:一个机器人位于一个m X n网格的左上角,机器人每次只能向下或者向右移动一步,机器人试图达到网格的右下角,总共有多少条不同的路径?
分析:
- 定义数组元素的含义:dp[i][j]的含义:当机器人从左上角走到(i,j)这个位置时,一共有dp[i][j]种路径。那么,dp[m-1][n-1]就是我们需要定义的数组。
- 找出关系数组元素间的关系式:由于机器人可以向下走或向右走,所以有两种方式到达,一种是从(i-1,j)这个位置走一步到达,另一种是从(i,j-1)这个位置走一步到达。所以关系式式dp[i][j] = dp[i-1][j]+dp[i][j-1]
- 找出初始值:dp[0][0...n-1] = 1;// 相当于最上面一行,机器人只能一直往右走。 dp[0...m-1][0] = 1;//相当于最左面一列,机器人只能一直往下走。
int uniquePaths(int m,int n){
if(m <= 0 || n <= 0){
return 0;
}
int[] [] dp = new int[m][n];
for(int i = 0;i < m;i++){
dp[i][0] = 1;
}
for(int i = 0;i < n;i++){
dp[0][i] = 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-1][n-1];
}