您的位置:首页 > 其它

【算法】动态规划的用法——01背包问题

2015-11-03 00:36 351 查看
动态规划的用法——01背包问题

问题主题:著名的01背包问题
问题描述:

有n个重量和价值分别为wi、vi的物品,现在要从这些物品中选出总重量不超过W的物品,求所有挑选方案中的价值最大值。

限制条件:

1<=N<=100

1<=wi 、vi<=100

1<=wi<=10000
样例:

输入

N=4

W
= {2, 1, 3, 2}

V
= {3, 2, 4, 2}

输出

W = 5(选择0,1,3号)


【解法一】



解题分析:


用普通的递归方法,对每个物品是否放入背包进行搜索


程序实现:

C++
[cpp] view
plaincopy





#include <stdio.h>

#include <tchar.h>

#include <queue>

#include "iostream"

using namespace std;

const int N = 4;

const int W = 5;

int weight
= {2, 1, 3, 2};

int value
= {3, 2, 4, 2};

int solve(int i, int residue)

{

int result = 0;

if(i >= N)

return result;

if(weight[i] > residue)

result = solve(i+1, residue);

else

{

result = max(solve(i+1, residue), solve(i+1, residue-weight[i]) + value[i]);

}

}

int main() {

int result = solve(0, W);

cout << result << endl;

return 0;

}


【解法二】


解题分析:

用记录结果再利用的动态规划的方法,上面用递归的方法有很多重复的计算,效率不高。我们可以记录每一次的计算结果,下次要用时再直接去取,以提高效率


程序实现:

C++
[cpp] view
plaincopy





#include <stdio.h>

#include <tchar.h>

#include <queue>

#include "iostream"

using namespace std;

const int N = 4;

const int W = 5;

int weight
= {2, 1, 3, 2};

int value
= {3, 2, 4, 2};

int record
[W];

void init()

{

for(int i = 0; i < N; i ++)

{

for(int j = 0; j < W; j ++)

{

record[i][j] = -1;

}

}

}

int solve(int i, int residue)

{

if(-1 != record[i][residue])

return record[i][residue];

int result = 0;

if(i >= N)

return result;

if(weight[i] > residue)

{

record[i + 1][residue] = solve(i+1, residue);

}

else

{

result = max(solve(i+1, residue), solve(i+1, residue-weight[i]) + value[i]);

}

return record[i + 1][residue] = result;

}

int main() {

init();

int result = solve(0, W);

cout << result << endl;

return 0;

}

Java
[java] view
plaincopy





package greed;

/**

* User: luoweifu

* Date: 14-1-21

* Time: 下午5:13

*/

public class Knapsack {

private int maxWeight;

private int[][] record;

private Stuff[] stuffs;

public Knapsack(Stuff[] stuffs, int maxWeight) {

this.stuffs = stuffs;

this.maxWeight = maxWeight;

int n = stuffs.length + 1;

int m = maxWeight+1;

record = new int
[m];

for(int i = 0; i < n; i ++) {

for(int j = 0; j < m; j ++) {

record[i][j] = -1;

}

}

}

public int solve(int i, int residue) {

if(record[i][residue] > 0) {

return record[i][residue];

}

int result;

if(i >= stuffs.length) {

return 0;

}

if(stuffs[i].getWeight() > residue) {

result = solve(i + 1, residue);

} else {

result = Math.max(solve(i + 1, residue),

solve(i + 1, residue - stuffs[i].getWeight()) + stuffs[i].getValue());

}

record[i][residue] = result;

return result;

}

public static void main(String args[]) {

Stuff stuffs[] = {

new Stuff(2, 3),

new Stuff(1, 2),

new Stuff(3, 4),

new Stuff(2, 2)

};

Knapsack knapsack = new Knapsack(stuffs, 5);

int result = knapsack.solve(0, 5);

System.out.println(result);

}

}

class Stuff{

private int weight;

private int value;

public Stuff(int weight, int value) {

this.weight = weight;

this.value = value;

}

int getWeight() {

return weight;

}

void setWeight(int weight) {

this.weight = weight;

}

int getValue() {

return value;

}

void setValue(int value) {

this.value = value;

}

}

原文链接




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: