动态规划0-1背包问题

最近看了一些简单的动态规划方面的例题 在学习的过程中发现 有的问题虽然不难 但是第一次看还是会有些问题

所以把自己弄0-1背包的问题拿出来给大家分享 不喜勿喷 网上资源特别多

讲解什么的就算了 其他人画的图都不错

递推关系

设所给0-1背包问题的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为i,i+1,…,n时0-1背包问题的最优值。由0-1背包问题的最优子结构性质,可以建立计算m(i,j)的递归式:


<!--[endif]-->

上式此时背包容量为j,可选择物品为i。此时在对xi作出决策之后,问题处于两种状态之一:

    (1)背包剩余容量是j,没产生任何效益;

    (2)剩余容量j-wi,效益值增长了vi ;

我写的代码 看完看有没有启发


package org.bq.dp;

/**
* 0-1背包问题
*
* @author 白强原创
* @version 1.0
*/
public class OneZero {
// 最大背包容量
private static final int M = 10;
// 物品数量
private static final int N = 3;
// 物品重量数组 给它数组前面加一个0项是为了更好的表达这种关系 比方从一个到全部物品的时候i=2的使用w[i]=4避免减1使用w[i-1]麻烦
private static final int[] w = { 0, 3, 4, 5 };
// 物品价值数组
private static final int[] v = { 0, 4, 5, 6 };

public static void main(String[] args) {
// 首先我们应该定义一个数组来记录选择的表 由于零的存在我应该吧他定义的大一些
int[][] select = new int[N + 1][M + 1];
int result = knapsack(select);
System.out.println("The max value is : " + result);
int leftSpace = M;
// 输出所选择的物品列表:
for (int i = N; i >= 1; i--) {
if (leftSpace >= w[i]) {
// 如何确定物品被选 只需要从价值表得到
// 它的价值和剩余物品容量对应的价值-价值表中上排的剩余物品容量减去本物品的重量的价值==当前物品的价值
if ((select[i][leftSpace] - select[i - 1][leftSpace - w[i]] == v[i])) {
System.out.println("物品 " + i + " 重量为: " + w[i] + " 价值为: "
+ w[i] + " is selected!");
// 如果第i个物品被选择,那么背包剩余容量将减去第i个物品的重量
leftSpace = leftSpace - w[i];
}
}
}
}

/**
* 这是程序的算法实现
*
* @param select是一个记录价值的数组它的下标
* [i][j] i代表当前放入物品从1到N j代表当前背包容量从1到M
* @return 最大价值
*/
public static int knapsack(int[][] select) {
// 当前放入物品为零很明显它的价值全是零
for (int j = 1; j <= M; ++j)
select[0][j] = 0;
// 基本算法思想上在装入一个或多个物品的时候让背包容量从1到最大 再看每一次的情况 首先能不能装 能装再看价值比较
for (int i = 1; i <= N; ++i) {
// 只要select[i][j] j=0即背包容量为0时,最大价值肯定为0
select[i][0] = 0;
// 背包容量j从小到大一直往上走直到M
for (int j = 1; j <= M; ++j) {
// 当前物品i的重量小于等于背包容量j,进行选择
if (w[i] <= j) {
/*
* 如果本物品的价值加上背包还能放物品的价值(如何得到 剩余物品重量=当前背包容量-当前物品,
* 得到剩余物品的重量后在上排查询得到剩余物品的价值) 如果大于上排的值则放入
*/
if ((v[i] + select[i - 1][j - w[i]]) > select[i - 1][j])
select[i][j] = v[i] + select[i - 1][j - w[i]];
else
// 直接使用上排的值
select[i][j] = select[i - 1][j];
} else {
// 当前物品还不能放入 所以还得使用上排的结果
select[i][j] = select[i - 1][j];
}
}
}

return select[N][M];

}
}


输出结果如下

看一个表格我画的 表示了这个放入的过程 可以更好看出变换




































































编号

0

1

2

3

4

5

6

7

8

9

10

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

4

4

4

4

4

4

4

4

2

0

0

0

4

5

5

5

9

9

9

9

3

0

0

0

4

5

6

6

9

10

11

11

重量w = { 0, 3, 4, 5 };价值v = { 0, 4, 5, 6 };

时间: 2024-11-13 17:47:04

动态规划0-1背包问题的相关文章

动态规划0—1背包问题

动态规划0-1背包问题 ? 问题描写叙述: 给定n种物品和一背包.物品i的重量是wi,其价值为vi,背包的容量为C.问应怎样选择装入背包的物品,使得装 入背包中物品的总价值最大? ? 对于一种物品,要么装入背包,要么不装.所以对于一种物品的装入状态能够取0和1.我们设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-11背包问题. 过程分析 数据:物品个数n=5,物品重量w[n]={0,2,2,6,5,4},物品价值V[n]={0,6,3,5,4,6}, (第0位,置为0,不參与计算,仅

动态规划--0,1背包问题(再也不怕类似背包问题了)

这种类型问题三大要素:总重量.每件物品重量.每件物品价值,问最终能够塞进背包中的价值最大是多少?应该怎么选择物品? 当然也不一定是这些,例如上节所说的矿工挖矿:总人数.挖每座矿的人数.每座矿的金子数. 也就是说,只要出现了这三大要素,都可以视为0,1背包问题(物品不可拆分) 动态规划三要素:边界.最优子结构.状态转移方程. 我们一步步进行解析: 初始化:物品总重量:c=8,物品类别:n=['a','b','c','d'],物品重量:w=[2,4,5,3],物品价值:v=[5,4,6,2] 假设我

动态规划算法实现部分——0/1背包问题

代码: import java.util.*; import java.util.Scanner; /* *动态规划思想解决0/1背包问题 */ public class Main{ public static void main(String[] args){ Scanner in=new Scanner(System.in); System.out.println("输入背包的容量"); int bagCap=in.nextInt(); //背包的容量 System.out.pri

动态规划算法求解0,1背包问题

首先我们来看看动态规划的四个步骤: 1. 找出最优解的性质,并且刻画其结构特性: 2. 递归的定义最优解: 3. 以自底向上的方式刻画最优值: 4. 根据计算最优值时候得到的信息,构造最优解 其中改进的动态规划算法:备忘录法,是以自顶向下的方式刻画最优值,对于动态规划方法和备忘录方法,两者的使用情况如下: 一般来讲,当一个问题的所有子问题都至少要解一次时,使用动态规划算法比使用备忘录方法好.此时,动态规划算法没有任何多余的计算.同时,对于许多问题,常常可以利用其规则的表格存取方式,减少动态规划算

[转载]动态规划之0-1背包问题

作者:Hawstein出处:http://hawstein.com/posts/dp-knapsack.html 一切都要从一则故事说起. 话说有一哥们去森林里玩发现了一堆宝石,他数了数,一共有n个. 但他身上能装宝石的就只有一个背包,背包的容量为C.这哥们把n个宝石排成一排并编上号: 0,1,2,-,n-1.第i个宝石对应的体积和价值分别为V[i]和W[i] .排好后这哥们开始思考: 背包总共也就只能装下体积为C的东西,那我要装下哪些宝石才能让我获得最大的利益呢? OK,如果是你,你会怎么做?

【动态规划】简单背包问题II

问题 B: [动态规划]简单背包问题II 时间限制: 1 Sec  内存限制: 64 MB提交: 21  解决: 14[提交][状态][讨论版] 题目描述 张琪曼:“为什么背包一定要完全装满呢?尽可能多装不就行了吗?” 李旭琳:“你说得对,这和墨老师曾告诉我们的‘日中则昃,月满则亏’是一个道理.”所以,现在的问题是,她们有一个背包容量为v(正整数,0≤v≤20000),同时有n个魔法石(0≤n≤30),每个魔法石有一个体积 (正整数).要求从n个魔法石中,任取若干个装入包内,使背包的剩余空间为最

【动态规划】完全背包问题

贵有恒,何必三更起五更眠:最无益,莫过一日曝十日寒. [动态规划]完全背包问题 时间限制: 1 Sec  内存限制: 64 MB 题目描述 话说张琪曼和李旭琳又发现了一处魔法石矿(运气怎么这么好?各种嫉妒羡慕恨啊),她们有一个最多能装m公斤的背包,现在有n种魔法石,每种的重量分别是W1,W2,…,Wn,每种的价值分别为C1,C2,…,Cn.若每种魔法石的个数足够多,求她们能获得的最大总价值. 输入 第一行为两个整数,即m,n. 以后每行为两个整数,表示每块魔法石的重量和价值. 输出 获得的最大总

动态规划解决0-1背包问题

这几天算法老师布置了一个作业是关于背包问题的,在这里记录一下解决的过程: 一:背包问题的描述 有n1,n2,n3....个物品,每个物品的重量为w1,w2,w3.....,每个物品的价值为v1,v2,v3....,现在有一个承重量为C的背包,求出要怎样放物品才能使的装入背包的物品价值总和最大.由于每个物品只有一个,并且只能选择放或不放,因此用0表示物体没有放进背包中,1表示物体放进背包中 二:分析过程(以具体的例题来分析) 题目描述: 现有一个可以承重为6的背包bag,以及3个物品,它们的重量分

求解0/1背包问题

动态规划 //求解0_1背包问题 //动态规划 #include<stdio.h> #define MaxN 20 #define MaxW 100 int knap(int f[MaxN][MaxW],int w[],int v[],int W,int n){ //动态规划求数组f[][] int i,r; for(i=0;i<=n;i++) f[i][0] = 0; for(r=0;r<=W;r++) f[0][r] = 0; for(i=1;i<=n;i++){ for

背包问题:0/1背包问题 普通背包问题(贪心算法只适用于普通背包问题)

//sj和vj分别为第j项物品的体积和价值,W是总体积限制. //V[i,j]表示从前i项{u1,u2,…,un}中取出来的装入体积为j的背包的物品的最大价值. 第一种:0/1背包问题 最大化 ,受限于  1)若i=0或j=0,  V[i,j] = 0 2)若j<si, V[i,j] = V[i-1,j] 3)若i>0且j>=si, V[i,j] = Max{V[i-1,j],V[i-1,j-si]+vi} 第二种:背包问题:在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部