一,怎么理解动态规划
动态规划(Dynamic Programming,简称DP)是运筹学的一个分支,它是解决多阶段决策过程最优化的一种数学方法。把多阶段问题变换为一系列相互联系的的单阶段问题,然后逐个加以解决。 这里提到动态规划其实是一种数学方法,是求解某类问题的一种方法,而不是一种特殊的算法,没有一个标准的数学表达式或明确定义的一种规则。 比如我们接触过的”排序算法“,”二叉树遍历算法“等,这些算法都是有固定范式的,遇到此类问题我们只需要照搬算法即可。
动态规划常见的问题
1,基础问题,例如斐波那契额数列和爬楼梯
2,背包问题
3,打家劫舍问题
4,股票问题
5,子序列问题
解决动态规划问题
要想完整的解决动态规划问题,我们除了对递推公式的应用,还需要理解并解决以下的问题:
1,注意定义时dp[]数组的理解
2,递推公式的掌握和理解
3,dp数组如何初始化
4,选择合理的遍历顺序
5,打印dp数组,结合递推数组的结果处理代码中存在的问题
以上就是动态规划问题的理解思路和步骤,将以上问题都做好,动态回话问题就迎刃而解了
二,动态规划问题
1,背包问题
题目描述
给定N个物品,每个物品有一个重量W和一个价值V。你有一个能装M重量的背包。问怎么装使得所装价值最大。每个物品只有一个。
输入格式
输入的第一行包含两个整数n, m,分别表示物品的个数和背包能装重量。
以后N行每行两个数Wi和Vi,分别表示每个物品的重量和价值。
输出格式
输出1行,包含一个整数,表示最大价值。
样例输入
5 11
1 1
2 6
5 18
6 22
7 28
样例输出
40
解题思路
我们可以使用动态规划的思想来解决。首先创建一个二维数组dp,其中dp[i][j]表示前i个物品放入容量为j的背包中所能获得的最大价值。然后遍历每个物品,对于每个物品,从背包容量j到物品重量Wi进行遍历,更新dp[i][j]的值。最后返回dp[n][m]即可。
代码
import java.util.Scanner;
public class beibaowenti01 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n =input.nextInt();
int m = input.nextInt();
int[] W = new int[n + 1];
int[] V = new int[n + 1];
for (int i = 1; i <= n; i++) {
W[i] = input.nextInt();
V[i] = input.nextInt();
}
int[][] a = new int[n + 1][m + 1];
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (j < W[i]) {
a[i][j] = a[i - 1][j];
} else {
a[i][j] = Math.max(a[i - 1][j], a[i - 1][j - W[i]] + V[i]);
}
}
}
System.out.println(a[n][m]);
}
}
2,最长公共子序列
输入两个字符序列,一个序列X和另一个序列Z,当Z中的所有元素都在X中存在,并且在X中的下标顺序是严格递增的,那么就把Z叫做X的子序列。
例如:Z=<a,b,f,c>是序列X=<a,b,c,f,b,c>的一个子序列,Z中的元素在X中的下标序列为<1,2,4,6>。
现给你两个序列X和Y,请问它们的最长公共子序列的长度是多少?
输入格式
输入数据有多组,每组有两行 ,每行为一个长度不超过500的字符串(输入全是大写英文字母(A,Z)),表示序列X和Y。
输出格式
每组输出一行,表示所求得的最长公共子序列的长度,若不存在公共子序列,则输出0。
样例输入
ABCBDAB
BDCABA
样例输出
4
解题思路
我们可以使用二维数组dp来存储X和Y的最长公共子序列的长度。dp[i][j]表示X的前i个字符和Y的前j个字符的最长公共子序列的长度。状态转移方程为:dp[i][j] = dp[i-1][j-1] + 1,如果X[i] == Y[j];否则,dp[i][j] = max(dp[i-1][j], dp[i][j-1])。最后输出dp[m][n],其中m和n分别为X和Y的长度。
代码
import java.util.Scanner;
public class zuichanggonggongzixuliechangdu {
public static void main(String[] args) {
Scanner input =new Scanner(System.in);
while(input.hasNext()) {
String x =input.next();
String y=input.next();
int [][]a=new int[x.length()+1][y.length()+1];
for(int i=1;i<=x.length();i++) {
for(int j=1;j<=y.length();j++) {
if(x.charAt(i-1)==y.charAt(j-1)) {
a[i][j]=a[i-1][j-1]+1;
}
else {
a[i][j]=Math.max(a[i-1][j], a[i][j-1]);
}
}
}
System.out.println(a[x.length()][y.length()]);
}
}
}
以上是两道动态规划的例题,用于帮大家更好的理解动态规划问题,下面这张图是力扣上的对于动态规划问题的解释,大家可以结合着自己练习一些题目,加强自己对动态规划问题的理解和解决能力。
新人小白,初来乍到,希望大家多多评论,一起交流学习!