本关任务:给定N个物品和一个背包,背包的容量为W, 假设背包容量范围在[0,15],第i个物品对应的体积和价值分别为W[i]和v[i]。
各种物品的价值和重量如下:
物品编号 1 2 3 4 5
重量W 3 4 7 8 9
价值V 4 5 10 11 13
求: 如何选择装入背包的物品,使得装入背包的物品的总价值为最大。
相关知识
为了完成本关任务,你需要掌握:
1.动态规划原理的方法;
2.0/1背包问题。
/*
本关任务:给定N个物品和一个背包,背包的容量为W, 假设背包容量范围在[0,15],第i个物品对应的体积和价值分别为W[i]和v[i]。各种物品的价值和重量如下:
物品编号 1 2 3 4 5
重量W 3 4 7 8 9
价值V 4 5 10 11 13
求: 如何选择装入背包的物品,使得装入背包的物品的总价值为最大。
*/
#include <stdio.h>
#include <stdlib.h>
// #define max(a,b) \
// ({ __typeof__ (a) _a = (a); \
// __typeof__ (b) _b = (b); \
// _a > _b ? _a : _b; })
#define N 5//goods num
#define BAGW 15
int main( void )
{
int w[N+1],v[N+1];
w[0]=0;
v[0]=0;
for (int i = 1; i < N+1; i++)//get goods's wight and value
{
scanf("%d %d",&w[i],&v[i]);
}
// for (int i = 0; i < N+1; i++)//get goods's wight and value
// {
// printf("%d %d",w[i],v[i]);
// printf("\n");
// }
printf("w v 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n");
// int cnt = 0;
// for (int i = 0; i < 16; i++)//假设背包容量范围在[0,15]
// {
// int bagW = BAGW;
// int **dp;
// dp = (int**)malloc(sizeof(int*)*(N+1));//line
// for (int k = 0; k < N+1; k++)//column
// {
// *(dp+k) = (int*)malloc(sizeof(int)*(BAGW+1));
//table of dp
// for(int j=0;j<BAGW+1;j++){
// dp[k][j]=0;
// }
// }
int dp[N+1][BAGW+1]={{0}};
for (int k = 1; k <= N; k++)
{
for (int j =1; j <= BAGW; j++)
{
if(j < w[k])
//包的容量比该商品体积小,装不下,此时的价值与前i-1个的价值是一样的,
//即V(i,j)=V(i-1,j)
{
dp[k][j]=dp[k-1][j];
// printf("dp[%d][%d]=%d\n",k,j,dp[k][j]);
}else
//还有足够的容量可以装该商品,但装了也不一定达到当前最优价值,
//所以在装与不装之间选择最优的一个,即V(i,j)=max{V(i-1,j),V(i-1,j-w(i))+v(i)}。
//V(i-1,j-w(i))+v(i) 表示装了第i个商品,背包容量减少w(i),但价值增加了v(i);
{
if(dp[k-1][j]>dp[k-1][j-w[k]]+v[k]){
dp[k][j]=dp[k-1][j];
}else{
dp[k][j]=dp[k-1][j-w[k]]+v[k];
}
// printf("dp[%d][%d]=%d\n",k,j,dp[k][j]);
}
}
}
for (int k = 0; k < N+1; k++)//动态规划表的输出
{
printf("%d %d ",w[k],v[k]);
for (int j = 0; j < BAGW+1; j++)
{
if(j==BAGW)
{
printf("%d",dp[k][j]);
continue;
}
printf("%d ",dp[k][j]);
}
printf("\n");
}
for (int k = 0; k <N+1; k++)//free two demens space
{
free(*(dp+k));
}
// }
return 0;
}