动态规划-01背包系列题

本文详细介绍了动态规划在解决01背包问题上的应用,包括基本的01背包问题解题思路、实现方法,以及扩展到的最多任务工资、数列不相邻数字最大和、判断指定和的子序列存在性等问题。通过建模、确定子问题、状态转移方程和边界条件,展示了动态规划在实际问题中的解决步骤和代码实现。
摘要由CSDN通过智能技术生成

动态规划-01背包系列题,选取动态规划中采用01背包模型解题思路的几个例题

1.01背包问题解题思路
2.01背包问题实现
3.01背包系列-最多任务工资
4.01背包系列-数列不相邻数字最大和
5.01背包系列-数列找到指定和子数列


1.01背包问题解题思路
从右到左进行解析,分析第n个物品的状态,第n个物品只有“放”和“不放“俩种状态,在“放”状态下,某些变量发生变化,以及放情况下,与前面子问题之间的联系。在“不放”状态下,即考虑前n-1个物品。
每个物品都有俩种状态,动态规划,相当于列出所有情况,从中挑选子问题的最优解。
所以首先要从后往前分析问题,给出状态转移方程,然后判定边界情况,然后从前往后实现代码,填充中间数组(一维数组,二维数组)。

2.01背包问题实现
题目:有一个包和n个物品,包的容量为m,每个物品都有各自的体积和价值。问当这n个物品放在包里而物品的体积总数不超过包的容量m时,如何让背包具有最大价值?

分析:
1.建模:使用数组分别存储这n个物品的体积和价值
v[n] = {v1,v2,v3,….vn};
w[n] = {w1,w2,w3,..wn};

2.确定子问题:n个物品加入容量为m的包里f(n,m),第n个物品有俩种选择,放或不放,如果放,包的剩余容量为m-vn,价值为wn + f(n-1,m-vn)
如果不放,包的剩余容量为m,价值为f(n-1,m)

3.状态转移方程:f(n,m) = max{wn+f(n-1,m-vn),f(n-1,m)}

4.边界情况:

  • n == 0 retutn 0
  • m ==0 return 0
  • m < 0 return f(n-1,m)

5.动态规划二维数组(画图更直观)

dp[i][j] = max{dp[i-1][j-vi]+wi,dp[i-1][j]}
dp[i][j]表示前i件物品中,选择若干件放在容量为j的包里的最大价值1
这里写图片描述
6..代码实现
代码中给出递归法和动态规划法,用以比较

public class Bags {
   
    public static void main(String[] args){
        int[] weight = {
  3,4,7,9,13};
        int[] volume = {
  2,4,3,5,7};
        int m = 11;
        int n = weight.length-1;
        int res = getMaxValue(volume,weight,m,n);
        System.out.println(res);
        int res_dp = getMaxValue_DP(volume,weight,m);
        System.out.println(res_dp);
    }

    /**
     * 使用二维数组保存中间结果
     * @param
     * @param m
     * @return
     */
    private static int getMaxValue_DP(int[] volume, int[] weight, int m) {
        if (volume.length == 0)
            return 0;
        if (m == 0)
            return 0;
        int[][] dp = new int[volume.length][m];
        //填充第一列
        for (int i = 0; i < dp.length; i++){
            if (volume[i] <= 1){
                dp[i][0] = dp[i][0] < weight[i] ? weight[i] : dp[i][0];
            }
        }
        //填充第一行
        for (int i = 0; i < m; i++){
            if (volume[0] <= i+1){
                dp[0][i] &#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值