【校招VIP】动态规划的简单理解及例子

08月10日 收藏 0 评论 1 前端开发

【校招VIP】动态规划的简单理解及例子

转载声明:文章来源https://blog.csdn.net/m0_53677355/article/details/123622479

动态规划是分治的延伸,通俗一点来说就是大事化小,小事化无的艺术,在将大问题化解为小问题的分治过程中,保存对这些小问题已经处理好的结果,并供后面处理更大规模的问题时直接使用这些结果。

1、动态规划具备了以下三个特点

(1)把原来的问题分解为几个相似的子问题
(2)所有的子问题都只需要解决一次
(3)储存子问题的解

2、动态规划的本质就是对问题状态的定义和状态转移方程的定义(状态以及状态之间的递推关系)

3、动态规划问题一般从以下四个角度考虑

(1)状态定义(定义的状态一定要形成递推关系)
(2)状态间的转移方程定义
(3)状态的初始化
(4)返回结果

4、使用场景:最大值/最小值,可不可行,是不是,方案个数

5、通过以下例题加深理解

(1)

状态F(i):第i项的值
状态转移方程:F(i)= F(i-1)+ F(i-2)
初始状态:F(0)= 0 , F(1)= 1
返回结果:F(n)
程序如下:

class Solution {
public int fib(int n) {
if(n < 2) return n;
final int MOD = 1000000007;
int p = 0,q = 0,r = 1;
for(int i = 2;i <= n;i++){
p = q;
q = r;
r = (p + q) % MOD;
}
return r;
}
}

(2)

状态F(i):字符串前i个字符是否可以被分割
状态转移方程:F(i):j < i && F(j) && [j+1,i]是否可以在词典中找到
初始状态:F(0):true 辅助状态
返回结果:F(字符串长度):f(s.size) f(s.length())

class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
boolean[] canBreak = new boolean[s.length() + 1];
canBreak[0] = true;
for(int i = 1;i <= s.length();i++){
for(int j = 0;j < i;j++){
if(canBreak[j] && wordDict.contains(s.substring(j,i))){
canBreak[i] = true;
break;
}
}
}
return canBreak[s.length()];
}
}

(3)

class Solution {
public int uniquePaths(int m, int n) {
int[][] f = new int[m][n];
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
if(j == 0){
f[i][0] = 1;
}else if(i == 0){
f[0][j] = 1;
}else{
f[i][j] = f[i][j-1] + f[i-1][j];
}
}
}
return f[m-1][n-1];
}
}

(4)

class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
if (triangle.isEmpty()) return 0;
int row = triangle.size();
int[][] f = new int[row][row];
f[0][0] = triangle.get(0).get(0);
for (int i = 1; i < row; i++) {
f[i][0] = f[i - 1][0] + triangle.get(i).get(0);
for (int j = 1; j <i; j++) {
f[i][j] = Math.min(f[i - 1][j - 1], f[i - 1][j]) + triangle.get(i).get(j);
}
f[i][i] = f[i - 1][i - 1] + triangle.get(i).get(i);
}
int minSum = f[row-1][0];
for(int j = 1; j < row; j++) {
minSum = Math.min(minSum, f[row-1][j]);
}
return minSum;
}
}

(5)

class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] f = new int[m][n];
f[0][0] = grid[0][0];
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
if(j == 0 && i != 0){
f[i][0] = f[i-1][0] + grid[i][0];
}else if(j != 0 && i == 0){
f[0][j] = f[0][j-1] + grid[0][j];
}else if(j != 0 && i != 0){
f[i][j] = Math.min(f[i-1][j],f[i][j-1]) + grid[i][j];
}
}
}
return f[m-1][n-1];
}
}
C 1条回复 评论
夏至末日

在大学没有那么优秀的经历怎么办

发表于 2022-12-01 21:00:00
0 0