0-1背包问题(动态规划)
来源:互联网 发布:希克森cba数据 编辑:程序博客网 时间:2024/05/17 02:05
01背包 : 在 N 件物品,每件物品的重量为data[1][0],data[2][0]……data[n][0],与之相对应的价值为data[1][1],data[2][1]……data[n][1], 取出若干件放在 能装重量为 M 的背包里,求能装的最大价值为?
C 版:
#include <stdio.h>#include <stdlib.h>int max(int a,int b){ if (a>b) return a; else return b;}int main(){ int n,m,i,j; int data[1001][2]; int f[1001][1001]; //最优值矩阵,f[n][m]为最后所装最大价值 即 最优值 scanf("%d%d",&n,&m); // n 表示n件物品,m 表示背包能背的最大重量 即 总承重 for(i=1;i<=n;i++) { scanf("%d%d",&data[i][0],&data[i][1]); //每件物品的重量,价值 } for(i=0;i<=m;i++) f[0][i]=0; for(i=0;i<=n;i++) f[i][0]=0; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { f[i][j]=0; if(j>=data[i][0]) //如果第 i 个物品重量 小于等于 总承重 { f[i][j]=max(f[i-1][j],f[i-1][j-data[i][0]]+data[i][1]); //按 f[i-1][j] 和 f[i-1][j-data[i][0]]+data[i][1] 哪个价值大,决定这件物品 是否被选择 //f[i-1][j-data[i][0]]+data[i][1] 即 j-data[i][0]的重量能背的最大价值 + 这件物品的价值 //f[i-1][j] 即 不装这件物品时的重量能背的最大价值 } else f[i][j]=f[i-1][j]; //如果第 i 个物品重量大于总承重 } } printf("%d\n",f[n][m]); system("pause"); return 0;}测试输入:
8 133 204 82 115 153 61 71 124 18
输出:
68
Java版:
Goods.java
public class Goods {private int weight;private int value;public Goods(int weight,int value){this.weight = weight;this.value = value;}public int getWeight() {return weight;}public int getValue() {return value;}public String toString(){return "[weight: " + weight + " " + "value: " + value + "]";}}KnapsackProblem.java
import java.util.ArrayList;public class KnapsackProblem {private Goods[] goods; //物品private int totalWeight; //totalWeight 表示背包能背的最大重量private int n; // n 表示n件物品private int[][] bestValues; //最优值矩阵private int bestValue; //最优值private ArrayList<Goods> bestSolution;//最优解的物品组成public KnapsackProblem(Goods[] goods, int totalWeight) { this.goods = goods; this.totalWeight = totalWeight; this.n = goods.length; if (bestValues == null) { bestValues = new int[n+1][totalWeight+1]; } }public void solve() {for (int i = 0; i <= n; i++) {bestValues[i][0] = 0;}for (int j = 0; j <= totalWeight; j++) {bestValues[0][j] = 0;}for (int i = 1; i <= n; i++) { //同 C版 描述 for (int j = 1; j <= totalWeight; j++) {if (j >= goods[i - 1].getWeight()) { int iweight = goods[i - 1].getWeight(); int ivalue = goods[i - 1].getValue();bestValues[i][j] = Math.max(bestValues[i - 1][j], bestValues[i - 1][j - iweight] + ivalue); } else { bestValues[i][j] = bestValues[i - 1][j]; } } } bestValue = bestValues[n][totalWeight]; if(bestSolution == null){ bestSolution = new ArrayList<Goods>(); } int tempWeight = totalWeight;for(int i=n;i >=1;i--){ if(bestValues[i][tempWeight] > bestValues[i-1][tempWeight]){ bestSolution.add(goods[i-1]); // goods[i-1] 表示第 i 个物品 tempWeight -= goods[i-1].getWeight(); }if(tempWeight == 0){ break; }} } public int[][] getBestValues() { return bestValues; } public int getBestValue() { return bestValue; } public ArrayList<Goods> getBestSolution() { return bestSolution; }}测试
KnapsackTest.java
public class KnapsackTest {public static void main(String[] args) { Goods[] goods = new Goods[] { new Goods(3,20), new Goods(4,8), new Goods(2,11), new Goods(5,15), new Goods(3,6), new Goods(1,7), new Goods(1,12), new Goods(4,18) }; int totalWeight = 12; KnapsackProblem kp = new KnapsackProblem(goods, totalWeight); kp.solve(); System.out.println(" -------- 该背包问题实例的解: --------- "); System.out.println("最优值:" + kp.getBestValue()); System.out.println("最优解【选取的物品】: "); System.out.println(kp.getBestSolution()); System.out.println("最优值矩阵:"); int[][] bestValues = kp.getBestValues(); for (int i=0; i < bestValues.length; i++) { for (int j=0; j < bestValues[i].length; j++) { System.out.printf("%-5d", bestValues[i][j]); } System.out.println(); } }}输出:
-------- 该背包问题实例的解: --------- 最优值:68最优解【选取的物品】: [[weight: 4 value: 18], [weight: 1 value: 12], [weight: 1 value: 7], [weight: 2 value: 11], [weight: 3 value: 20]]最优值矩阵:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20 20 20 20 20 20 20 20 20 20 20 0 0 0 20 20 20 20 28 28 28 28 28 28 28 0 0 11 20 20 31 31 31 31 39 39 39 39 39 0 0 11 20 20 31 31 31 35 39 46 46 46 46 0 0 11 20 20 31 31 31 37 39 46 46 46 52 0 7 11 20 27 31 38 38 38 44 46 53 53 53 0 12 19 23 32 39 43 50 50 50 56 58 65 65 0 12 19 23 32 39 43 50 50 57 61 68 68 68
时间复杂度为O(n*m),基本已经不能再优化了,但空间复杂度却可以优化到O(v)
改进版(将最优矩阵改为使用一维数组):
C++版:
#include <cstdio>#include <cstring>int bestValues[1005];int main(){ int n,m;// n 表示n件物品,m 表示背包能背的最大重量 即 总承重 int i,j; while(scanf("%d %d",&n,&m)&&(n+m)) { int weight[1001],value[1001]; for (i=1;i<=n;i++) { scanf("%d",&weight[i]); scanf("%d",&value[i]); } memset(bestValues,0,sizeof(bestValues));//数组初始化为0 for (i=1;i<=n;i++)//从第一个物品开始一直到第n个物品 for(j=m;j>=weight[i];j--)//从背包装满的状态开始,且第j个背包状态重量应该要大于等于第i个物品的重量 if (bestValues[j-weight[i]]+value[i]>bestValues[j]){//如果第j-1个状态放入第i个的物品,并且放入后总价值大于第j个状态的价值 bestValues[j] = bestValues[j-weight[i]]+value[i]; //则第j-1个状态时选择放入第i个的物品 } printf("%d\n",bestValues[m]); } return 0;}
0 0
- 0/1背包问题动态规划详解
- 动态规划解0-1背包问题
- 0/1背包问题动态规划详解
- 动态规划 ------0-1背包问题
- 0/1背包问题动态规划详解
- 动态规划解决0-1背包问题
- 0/1背包问题动态规划详解
- 0-1背包问题--动态规划解法
- 动态规划解0-1背包问题
- 0-1背包问题动态规划
- 0-1背包问题,动态规划求解
- 动态规划解决0-1背包问题
- 0/1背包问题动态规划详解
- 动态规划---0-1背包问题
- 动态规划解决0-1背包问题
- 动态规划解0-1背包问题
- 0/1背包问题----动态规划实现
- 动态规划0—1背包问题
- 规则引擎Visual Rules Solution—关联决策表
- 日志框架NLog之将日志发送到邮件
- 获得月,年,季的第一天和最后一天
- 一个可复用的C++ 3阶实方阵类和4阶实方阵类(兼容与扩展了DX中的4阶实方阵类);四元数(quaternion)模板类的使用
- java 比较时间
- 0-1背包问题(动态规划)
- if和else的大bug
- POJ1611:The Suspects【并查集】
- Java多线程
- 理想在前,现实在后
- IOS 实现植物大战僵尸
- gnuplot(知识介绍及demo图)
- NetBeans的(默认)快捷键
- App Thinning功能中其实有三个独立的机制,分别是App Slicing、on-demand resources以及Bitcode,它们在节省iOS应用资源方面发挥着各自的作用。 iOS 9的