原文地址:http://blog.csdn.net/ljmingcom304/article/details/50328141

本文出自:【梁敬明的博客】

1.动态规划  

  什么是动态规划?动态规划就是将一个大问题不断向下拆分成小问题,直到拆分出的小问题可以求出其解,然后将小问题的解不断的向上合并,最终得到大问题的解决方案。

2.背包问题  

  一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大?

3.算法分析

  假设前n个物品,总承重为j,物品的重量为w,其最大价值为v[n,j]。

  在背包的总承重不变的前提下,一个物品是否放入背包中直接影响到后面的物品是否能放入到背包中,即一个物品很重同事物品价值又很低时,若装入背包中直接导致其他更多的物品无法放入背包中,从而使得背包中的最大总价值变低。

  当背包的承重为0,或者不将物品放入背包时,背包中的最大总价值均为0,即v[n,0]=v[0,n]=0。

  放入当前物品n超过背包的最大承重时,则无法将该物品放入背包中,即v[n,j]=v[n-1,j]。 

  放入当前物品n不超过背包的最大承重时,则当前物品放入背包时的最大价值为vn+v[n-1,j-wn],不放入背包时的最大价值为v[n-1,j],因此对于当前物品是否放入背包中所能获得的最大价值为v[n,j]=max{ v[n-1,j],vn+v[n-1,j-wn] }。 

动态规划



  上表从上往下,由左至右依次遍历。假设F3的背包承重为3,此时物品的重量为4,所以该物品无法放入背包中,此时背包可以获得的最大总价值为E3的最大总价值25。假设E10的背包承重为10,此时物品的重量为4,所以该物品可以放入背包中,当该物品不放入背包中时,背包的价值为D10的最大价值62,放入背包中时背包的价值为D6的最大价值加上该物品的价值,结果为77,因此最终得出E10的最大价值为77。

  创建物品对象,存在重量和价值两种属性。

public class Knapsack{
/** 物品重量 */
private int weight;
/** 物品价值 */
private int value; public Knapsack(int weight, int value) {
this.weight = weight;
this.value = value;
} public int getWeight() {
return weight;
} public void setWeight(int weight) {
this.weight = weight;
} public int getValue() {
return value;
} public void setValue(int value) {
this.value = value;
} }

 按照动态规划算法将物品放入背包中。

public class DTGHProblem {

    // 所有的物品
private Knapsack[] bags;
// 物品的数量
private int n;
// 背包总承重
private int totalWeight;
// 第一维:当前第几个物品;第二维:当前的背包承重;值:当前背包最大价值
private int[][] bestValues;
// 最终背包中最大价值
private int bestValue; public DTGHProblem(Knapsack[] bags, int totalWeight) {
this.bags = bags;
this.totalWeight = totalWeight;
this.n = bags.length;
if (bestValues == null) {
// 考虑0的状态+1,防止数组角标越界
bestValues = new int[n + 1][totalWeight + 1];
}
} public void solve() {
// 遍历背包的承重
for (int j = 0; j <= totalWeight; j++) {
// 遍历指定物品
for (int i = 0; i <= n; i++) {
// 当背包不放入物品或承重为0时,其最大价值均为0
if (i == 0 || j == 0) {
bestValues[i][j] = 0;
} else {
// 如果第 i个物品重量大于总承重,则最优解存在于前 i-1 个背包中
if (j < bags[i - 1].getWeight()) {
bestValues[i][j] = bestValues[i - 1][j];
} else {
// 如果第 i个物品不大于总承重,则最优解要么是包含第 i个背包的最优解,
// 要么是不包含第 i个背包的最优解, 取两者最大值
int weight = bags[i - 1].getWeight();
int value = bags[i - 1].getValue();
bestValues[i][j] = Math.max(bestValues[i - 1][j], value
+ bestValues[i - 1][j - weight]);
}
}
}
} bestValue = bestValues[n][totalWeight];
} public int getBestValue() {
return bestValue;
} }

最终测试结果:90

public class DTGHTest {
public static void main(String[] args) {
Knapsack[] bags = new Knapsack[] { new Knapsack(2, 13),
new Knapsack(1, 10), new Knapsack(3, 24), new Knapsack(2, 15),
new Knapsack(4, 28), new Knapsack(5, 33), new Knapsack(3, 20),
new Knapsack(1, 8) };
int totalWeight = 12;
DTGHProblem problem = new DTGHProblem(bags, totalWeight); problem.solve();
System.out.println(problem.getBestValue());
}
}

欢迎关注我的微信公众号:“”Java面试通关手册(坚持原创,分享美文,分享各种Java学习资源,面试题,以及企业级Java实战项目回复关键字免费领取):

动态规划_01背包问题_Java实现的更多相关文章

  1. 回溯算法_01背包问题_Java实现

    原文地址:http://blog.csdn.net/ljmingcom304/article/details/50314839 本文出自:[梁敬明的博客] 1.回溯算法 回溯算法也叫试探法,通俗的将就 ...

  2. 贪心算法_01背包问题_Java实现

    原文地址:http://blog.csdn.net/ljmingcom304/article/details/50310789 本文出自:[梁敬明的博客] 1.贪心算法 什么是贪心算法?是指在对问题进 ...

  3. [Dynamic Programming]动态规划之背包问题

    动态规划之背包问题 例题 现有4样物品n = ['a', 'b', 'c', 'd'],重量分别为w = [2, 4, 5, 3],价值分别为v = [5, 4, 6, 2].背包最大承重c = 9. ...

  4. 记录结果再利用的"动态规划"之背包问题

    参考<挑战程序设计竞赛>p51 https://www.cnblogs.com/Ymir-TaoMee/p/9419377.html 01背包问题 问题描述:有n个重量和价值分别为wi.v ...

  5. 【动态规划/多重背包问题】POJ1014-Dividing

    多重背包问题的优化版来做,详见之前的动态规划读书笔记. dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为: dp[i][j]=mi(dp[i-1][j ...

  6. 【Luogu】【关卡2-15】动态规划的背包问题(2017年10月)【还差一道题】

    任务说明:这是最基础的动态规划.不过如果是第一次接触会有些难以理解.加油闯过这个坎. 01背包二维数组优化成滚动数组的时候有坑有坑有坑!!!必须要downto,downto,downto 情景和代码见 ...

  7. python 动态规划(背包问题和最长公共子串)

    背包问题 现在要往一个可以装4个单位重量的背包里怎么装价值最高:A重量1个单位,价值15:B重量3个单位,价值20:C重量4个重量,价值30 使用动态规划填充空格 class SolutionBag: ...

  8. poj 1742 Coins (动态规划,背包问题)

    Coins Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 32977   Accepted: 11208 Descripti ...

  9. 九度OJ 1455 珍惜现在,感恩生活 -- 动态规划(背包问题)

    题目地址:http://ac.jobdu.com/problem.php?pid=1455 题目描述: 为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元, ...

随机推荐

  1. [C/C++] 虚函数机制

    转自:c++ 虚函数的实现机制:笔记 1.c++实现多态的方法 其实很多人都知道,虚函数在c++中的实现机制就是用虚表和虚指针,但是具体是怎样的呢?从more effecive c++其中一篇文章里面 ...

  2. jQuery 获取和设置radio 和 checkbox 值的操作

    jquery 中的val(),可以取值也可赋值,表单元素中的radio和checkbox是比较常用的控件,下面说说对它们的取值和赋值的使用 1.取值 表单如下: <div class=" ...

  3. 洛谷P3656 展翅翱翔之时 (はばたきのとき)(洛谷2017.3月赛round1 t4)

    题目背景 船が往くよミライへ旅立とう 船只启航 朝未来展开旅途 青い空笑ってる(なにがしたい?) 湛蓝天空露出微笑(想做些什么?) ヒカリになろうミライを照らしたい 化作光芒吧 想就此照亮未来 輝きは ...

  4. Python常忘的进阶知识(下)

    0.目录 1.装饰器 1.1 为每个函数都增加一个功能 1.2 装饰器只是一种模式 1.3 语法糖 1.4 函数需要传递参数,该如何更改装饰器? 1.5 函数需要传递关键字参数,该如何更改装饰器? 2 ...

  5. Interviewe HDU - 3486( 暴力rmq)

    面试n个人,可以分任意组数,每组选一个,得分总和严格大于k,问最少分几组 就是暴力嘛...想到就去写吧.. #include <iostream> #include <cstdio& ...

  6. SQL注入漏洞知识总结

    目录: 一.SQL注入漏洞介绍 二.修复建议 三.通用姿势 四.具体实例 五.各种绕过 一.SQL注入漏洞介绍: SQL注入攻击包括通过输入数据从客户端插入或“注入”SQL查询到应用程序.一个成功的S ...

  7. 【字符串】manacher算法

    Definition 定义一个回文串为从字符串两侧向中心扫描时,左右指针指向得字符始终相同的字符串. 使用manacher算法可以在线性时间内求解出一个字符串的最长回文子串. Solution 考虑回 ...

  8. selenium - webdriver - 定位一组元素

    八种方法: find_elements_by_id() find_elements_by_name() find_elements_by_class_name() find_elements_by_t ...

  9. [USACO12DEC] 逃跑的BarnRunning Away From…(主席树)

    [USACO12DEC]逃跑的BarnRunning Away From- 题目描述 It's milking time at Farmer John's farm, but the cows hav ...

  10. Linux常用网络工具:hping高级主机扫描

    之前介绍了主机扫描工具fping,可以参考我写的<Linux常用网络工具:fping主机扫描>. hping是一款更高级的主机扫描工具,它支持TCP/IP数据包构造.分析,在某些防火墙配置 ...