编程中十大常用算法:(三)动态规划算法

理论介绍

动态规划(Dynamic Programming, DP)算法的核心思想为:将大问题划分成小问题进行解决,从而一步步获取最优解的处理算法。
动态规划算法与分治算法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治算法不同的是,适合于用动态规划求解的问题,经分解得到的子问题往往不是相互独立的(即下一子阶段的求解是建立在上一子阶段的解的基础之上,进行进一步的求解)。动态规划算法可以通过填表的方式来逐步推进,得到最优解。

实际问题:背包问题

问题:有一个背包,容量为4,现有如下物品
在这里插入图片描述
要求
(1)要求达到的目标为装入背包的总价值最大,并且重量不能超出容量;
(2)要求装入的物品不能重复。

分析
(1)背包问题主要是指一个给定容量的背包、若干具有一定价值和重量的物品,如何选择物品放入背包使得物品的价值最大。背包问题又可分为:01背包和完全背包(完全背包是指每种物品都有无限件可用)。
(2)上述问题属于01背包,即每件物品最多放一个。
(3)动态规划算法解决此类问题的主要思想为:每次遍历到第i个物品,根据w[i]和v[i]来确定是否需要将该物品放入背包中。即对于给定的n个物品,设置v[i]、w[i]分别表示第i个物品的价值和重量,C为背包的容量;令v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值。伪代码如下:
1) v[i][0]=v[0][j]=0; //表示填入表的第一行和第一列是0
2)当w[j]>j时,v[i][j]=v[i-1][j] //当准备加入新增的物品的容量大于当前背包的容量时,就直接使用上个单元格的装入策略
3)当j>=w[i]时:v[i][j]=max{v[i-1][j],v[i]+v[i-1][j-w[i]]} //当准备加入的新增物品的容量小于等于当前背包的容量

代码实现(Java)



package com.zq.dp;

 

public class DP_01 {

  public static void main(String[] args) {

     int[] w= {1,4,3};//物品的重量

     int[] val= {1500,3000,2000};//物品的价值

     int c=4;//背包的容量

     int n=val.length;//物品的个数

     

     int[][] v=new int[n+1][c+1];//表示前i个物品中能够装入容量为j的背包中的最大价值

     //初始化第一行和第一列为0

     for(int i=0;i<v.length;i++) {

       v[i][0]=0;

     }

     for(int i=0;i<v[0].length;i++) {

       v[0][i]=0;

     }

     

     //DP算法解决01背包问题

     for(int i=1;i<v.length;i++) {

       for(int j=1;j<v[0].length;j++) {

          if (w[i-1]>j) {

            v[i][j]=v[i-1][j];

          }else {

            v[i][j]=Math.max(v[i-1][j], val[i-1]+v[i-1][j-w[i-1]]);

          }

       }

     }

     System.out.print("最大价值为:"+v[n][c]);

     

  }

}

 

结果

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值