数据结构-五大基本算法-动态规划

这篇博客介绍了如何使用动态规划解决经典的0-1背包问题,通过一个实例展示了如何在Java中实现找到装入背包中物品的总价值最大化的算法。博主分享了一个可能不够精简的解决方案,并邀请读者分享更优的算法。

用于求解某种最优性质的问题,动态规划与分治法类似。

例题:

0-1 背包问题:有n种物品和一背包,物品i的重量是wi,其价值为vi,其中wi 和 vi均为正整数,背包的容量为w,现需要考虑如何 选择装入背包的物品,使得装入背包中物品的总价值最大?分析一下:

 

 

目标函数:从i个物品 累计求和 i个物品 = n 的总价值

约束条件:当 i个物品的重量 <=背包的容量,x 取值 0【不放入】,1 【放入】

 

分析下这三种情况:

第一种情况:如果 i=0 表示没有放入物体,w=0,表示重量为0 所以为 0

第二种情况: 当 当前物品的重量大于背包总重量 ,当前物体不放入背包

第三种情况,当 当前物品的 重量小于背包总重量,且 判断,如果当前物品放入背包,求当前物品放入背包后的 总价值 或 当前物品不放入背包,求背包可能容纳的总价值,MAX二者取一。

i 物品 \ W 重量

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

1

0

0

0

4

4

4

4

4

4

4

4

4

4

4

4

4

4

4

2

0

0

0

4

5

5

5

9

9

9

9

9

9

9

9

9

9

9

3

0

0

0

4

5

5

5

10

10

10

14

14

14

14

19

19

19

19

4

0

0

0

4

5

5

5

10

11

11

14

15

16

16

19

21

21

21

5

0

0

0

4

5

5

5

10

13

13

14

15

17

18

19

21

23

24

分析表格:

当重量 w 越来越大时,我们可以判断 物品 i 是否能放入 每一次变化的 递增+1 中,一共递增 17次,因为我们可容纳的重量是17

java 求出最优解:

 


/**
 * @Author wuxiaotian
 * @Date 2021/8/26 11:00
 * @Version C1.4
 */
public class Test03 {
     void OutPutKnapsackDp(int n,int W, int[] weights,int[] values,int[][] c){
         int[] x = new int[5]; //n 表示所有的 物品总数
         int i = 0;
         for ( i = n; i > 0; i--) {
             if(W - 1 >= 0) {
                 if (c[i][W - 1] == c[i - 1][W - 1]) { //重量为w 的最优选择的背包中不包含该物品 判断当前这个物品 放入和不放入价值相等得话 就不放入
                     x[i - 1] = 0; //不放入该物品
                 } else {
                     x[i - 1] = 1; //放入该物品
                     System.out.println("总总量:" + W + "当前物品重量:" + weights[i] + "剩余重量:" + (W - weights[i]));
                     W = W - weights[i]; //更新背包目前的最大容量 总容量 - 当前物品容量
                 }
             }
           
         }


         if(c[1][W] == 0){ //第一个物品不放入背包
             x[0] = 0;
         }else{
             x[0] = 1; //第一个物品放入背包
         }

         for (int j = 0; j <n; j++) {
             if(x[j] == 1){
                 System.out.println(String.format("重量为%d: 价值为%d:",weights[j+1],values[j+1]));
             }
         }
     }

    public static void main(String[] args) {
        Test03 test03 = new Test03();
        int n = 4; //物品个数
        int W = 17; //总容量
        int[] weights = new int[] {3,4,7,8,9};
        int[] values = new int[] {4,5,10,11,13};

        int [][] c =new int[5][17];
        c[0] = new int[] {0 ,0 ,4, 4 ,4 ,4, 4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4 ,4, 4};
        c[1] = new int[] {0 ,0 ,4, 5, 5, 5, 9, 9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9 ,9};
        c[2] = new int[] {0, 0, 4, 5, 5, 5, 10, 10, 10, 14, 14, 14, 14, 19, 19, 19, 19};
        c[3] = new int[] {0, 0, 4, 5, 5, 5, 10, 11, 11, 14, 15, 16, 16, 19, 21, 21, 21};
        c[4] = new int[] {0, 0, 4, 5, 5, 5, 10, 13, 13, 14, 15, 17, 18, 19, 21, 23, 24};

        for (int i = 0; i <5; i++) {
            for (int j = 0; j < weights.length; j++) {
                c[i][j] = j;
            }
        }
        test03.OutPutKnapsackDp(n,W,weights,values,c);
    }
}

由于时间原因,以上算法可能不够精简,仅仅实现了功能,小伙伴们有更好的算法可以私聊我,一起学习丫

12篇学通csharp网络编程——第四篇 TCP应用编程 12篇学通csharp网络编程——第三篇 HTTP应用编程(下) 12篇学通csharp网络编程——第二篇 HTTP应用编程(上) 12篇学通csharp网络编程——第一篇 基础之进程线程 Lucene(1)lucene,你也会(7篇)——第一篇 快速入门 MongoDB(8)8天学通MongoDB——第八天 驱动实践 8天学通MongoDB——第七天 运维技术 8天学通MongoDB——第六天 分片技术 8天学通MongoDB——第五天 主从复制 8天学通MongoDB——第四天 索引操作 8天学通MongoDB——第三天 细说高级操作 8天学通MongoDB——第二天 细说增删查改 8天学通MongoDB——第一天 基础入门 UML系列(4)团队沟通利器之UML——类图 团队沟通利器之UML—— 序列图 团队沟通利器之UML——用例图 团队沟通利器之UML——活动图 wcf系列(5)wcf系列学习5天速成——第五天 服务托管 wcf系列学习5天速成——第四天 wcf之分布式架构 wcf系列学习5天速成——第三天 事务的使用 wcf系列5天速成——第二天 binding的使用(2) wcf系列5天速成——第一天 binding的使用(1) wpf系列(8)8天入门wpf—— 第八天 最后的补充 8天入门wpf—— 第七天 画刷 8天入门wpf—— 第六天 细说控件 8天入门wpf—— 第五天 数据绑定 8天入门wpf—— 第四天 模板 8天入门wpf—— 第三天 样式 8天入门wpf—— 第二天 xaml详解 8天入门wpf—— 第一天 基础概念介绍 并行开发(8)8天玩转并行开发——第八天 用VS性能向导解剖你的程序 8天玩转并行开发——第七天 简要分析任务与线程池 8天玩转并行开发——第六天 异步编程模型 8天玩转并行开发——第五天 同步机制(下) 8天玩转并行开发——第四天 同步机制(上) 8天玩转并行开发——第三天 plinq的使用 8天玩转并行开发——第二天 Task的使用 8天玩转并行开发——第一天 Parallel的使用 多线程系列(5)5天不再惧怕多线程——第五天 线程池 5天不再惧怕多线程——第四天 信号量 5天不再惧怕多线程——第三天 互斥体 5天不再惧怕多线程——第二天 锁机制 5天不再惧怕多线程——第一天 尝试Thread 经典算法专题(21)经典算法题每日演练——第二十一题 十字链表 经典算法题每日演练——第二十题 三元组 经典算法题每日演练——第十九题 双端队列 经典算法题每日演练——第十八题 外排序 经典算法题每日演练——第十七题 Dijkstra算法 经典算法题每日演练——第十六题 Kruskal算法 经典算法题每日演练——第十五题 并查集 经典算法题每日演练——第十四题 Prim算法 经典算法题每日演练——第十三题 赫夫曼树 经典算法题每日演练——第十二题 线段树 经典算法题每日演练——第十一题 Bitmap算法 经典算法题每日演练——第十题 树状数组 经典算法题每日演练——第九题 优先队列 经典算法题每日演练——第八题 AC自动机 经典算法题每日演练——第七题 KMP算法 经典算法题每日演练——第六题 协同推荐SlopeOne 算法 经典算法题每日演练——第五题 字符串相似度 经典算法题每日演练——第四题 最长公共子序列 经典算法题每日演练——第三题 猴子吃桃 经典算法题每日演练——第二题 五家共井 经典算法题每日演练——第一题 百钱买百鸡 开发利器系列(1)介绍一个小工具 Linqer 那点所谓的分布式(2)那点所谓的分布式——memcache 那点所谓的分布式——redis 树结构专题(5)6天通吃树结构—— 第五天 Trie树 6天通吃树结构—— 第四天 伸展树 6天通吃树结构—— 第三天 Treap树 6天通吃树结构—— 第二天 平衡二叉树 6天通吃树结构—— 第一天 二叉查找树 算法速成系列(15)算法系列15天速成——第十五天 图【下】(大结局) 算法系列15天速成——第十四天 图【上】 算法系列15天速成——第十三天 树操作【下】 算法系列15天速成——第十二天 树操作【中】 算法系列15天速成——第十一天 树操作(上) 算法系列15天速成——第十天 栈 算法系列15天速成——第九天 队列 算法系列15天速成——第八天 线性表【下】 算法系列15天速成——第七天 线性表【上】 算法系列15天速成——第六天 五大经典查找【下】 算法系列15天速成——第五天 五大经典查找【中】 算法系列15天速成——第四天 五大经典查找【上】 算法系列15天速成——第三天 七大经典排序【下】 算法系列15天速成——第二天 七大经典排序【中】 算法系列15天速成——第一天 七大经典排序【上】 算法洗脑系列(8)算法洗脑系列(8篇)——第八篇 概率思想 算法洗脑系列(8篇)——第七篇 动态规划 算法洗脑系列(8篇)——第六篇 回溯思想 算法洗脑系列(8篇)——第五篇 分治思想 算法洗脑系列(8篇)——第四篇 枚举思想 算法洗脑系列(8篇)——第三篇 贪心思想 算法洗脑系列(8篇)——第二篇 递归思想 算法洗脑系列(8篇)——第一篇 递推思想 天籁数学(3)天籁数学——数列篇(3) 天籁数学——数列篇(2) 天籁数学——数列篇(1) 图形图像(1)玩玩图形图像——第一篇:图片灰度化 小爬虫系列(4)玩玩小爬虫——抓取时的几个小细节 玩玩小爬虫——抓取动态页面 玩玩小爬虫——试搭小架构 玩玩小爬虫——入门
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值