您的位置:首页 > 其它

0/1背包问题简析备忘

2011-08-10 23:27 141 查看
主要就是参照百度百科来的,本文目的是自己学习备忘。

问题描述:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
测试数据:
1
物品数 5, 背包容量 100, 重量及价格
77 92   22 22   29 87   50 46   99 90

2
物品数 8, 背包容量 200, 重量及价格 
79 83   58 14   86 54   11 79   28 72   62 52   15 48   68 62

解法1,dp方法(同时打印出选了哪些物品1表示选,0表示不选):

#include <stdio.h>

#define N 5

#define V 100

#if 0

int c[V + 1] = {0, 15, 10, 35, 18, 25 };//volume = 45

int w[V + 1] = {0, 20, 15, 30, 25, 23 };

#else

int c[V + 1] = {0, 77, 22, 29, 50, 99 };//volume = 100

int w[V + 1] = {0, 92, 22, 87, 46, 90 };

#endif

int f
[V + 1];

int flag[N + 1];

void trace_back ()

{

int i = 1;

int v = V;

for (i = N; i > 0; --i)

{

if (f[i][v] != f[i-1][v])

{

v -= c[i];

flag[i] = 1;

}

}

for (i = 1; i <= N; i++)

printf ("%d", flag[i]);

printf ("\n");

}

int main(int argc, char * argv[])

{

int i = 1;

int v = 0;

for (i = 1; i < N; ++i)

{

for (v = V; v > 0; --v)

{

if (v >= c[i])

f[i][v] = (f[i-1][v] > f[i-1][v-c[i]] + w[i]) ?

f[i-1][v] : f[i-1][v-c[i]] + w[i];

else

f[i][v] = f[i-1][v];

}

}

f
[V] = f[i-1][V] > f[i-1][V-c[i]] + w[i] ?

f[i-1][V] : f[i-1][V-c[i]] + w[i];

printf ("Max value : %d\n", f
[V]);

trace_back ();

return 0;

}

以上算法,空间上可以优化,既f可以用一维数组,循环部分改为如下就可以了:

//注意其中内层循环v必须是递减的,以保证后面用的f[v-c[i]]时用的是i-1状态时存下的值。

for (i = 1; i < N; ++i)

{

for (v = V; v >= c[i]; --v)

{

f[v] = f[v] > f[v - c[i]] + w[i] ?

f[v] : f[v - c[i]] + w[i];

}

}

f[V] = f[V] > f[V - c[i]] + w[i] ?

f[V] : f[V - c[i]] + w[i];

printf ("Max value : %d\n", f[V]);

递归解法如下:#include <stdio.h>#define N 5#define V 100#define MAXSIZE 10#if 0 int c[MAXSIZE + 1] = { 15, 10, 35, 18, 25 };//volume = 45int w[MAXSIZE + 1] = { 20, 15, 30, 25, 23 };#elseint c
= { 77, 22, 29, 50, 99 };//volume = 100int w
= { 92, 22, 87, 46, 90 };#endifint F (int n, int v){ int temp1 = 0; int temp2 = 0; if (n == 0) return 0; if ( v >= c[n-1]) temp1 = F (n - 1, v - c[n-1]) + w[n-1]; temp2 = F (n - 1, v); return temp1 > temp2 ? temp1 : temp2;}int main (int argc, char *argv[]){ printf ("%d\n", F (N, V)); return 0;}时间和空间上都稍优一点,可见递归并不是低效的代名词。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: