动态规划算法

 一,怎么理解动态规划

动态规划(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()]);
				
			}
		}
		}

以上是两道动态规划的例题,用于帮大家更好的理解动态规划问题,下面这张图是力扣上的对于动态规划问题的解释,大家可以结合着自己练习一些题目,加强自己对动态规划问题的理解和解决能力。

新人小白,初来乍到,希望大家多多评论,一起交流学习!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CT.狭路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值