0/1背包问题和完全背包问题
一、0/1背包问题
(一)问题描述
现有一最大承重c的背包;另有有N件物品,编号为i的物品,重量为wi,所占价值为vi。
每件物品只有一件,可以选择放或不放。问在不超过背包最大承重的情况下,最多能获得多少价值?
(二)输入
第一行输入物品的件数N;其后N行分别输入第i件物品的重量和价值;
最后一行输入背包的最大承重。
(三)输出
获得的最大价值
(四)样例输入
3
4 2
6 4
7 5
10
(五)样例输出
6
(六)问题分析
采用动态规划,数据采用二维数组或一维数组存储。
(七)代码
1.二维数组存储方式
#include <stdio.h>
#define MAXNUM 9999
#define MAX(a,b) a>b?a:b
int N; //物品的个数
int w[MAXNUM]; //物品i的质量
int v[MAXNUM]; //物品i的价值
int c; //背包的最大承重
int f[MAXNUM][MAXNUM]; //f表示前i个获得的最大价值
int main()
{
//freopen("test.in","r",stdin);
scanf("%d",&N);
for (int i=1; i<=N; i++)
scanf("%d%d",&w[i],&v[i]);
scanf("%d",&c);
for (int i=0; i<=N; i++)
for (int j=0; j<=c; j++)
if (i==0||j==0)
f[i][j]=0;
for (int i=1; i<=N; i++)
for (int j=1; j<=c; j++)
if (j<w[i]) f[i][j]=f[i-1][j];
else f[i][j]=MAX(f[i-1][j], f[i-1][j-w[i]]+v[i]);
printf("%d\n",f[N][c]);
//fclose(stdin);
return 0;
}
2.一维数组存储方式
#include <stdio.h>
#define MAXNUM 9999
#define MAX(a,b) a>b?a:b
int N; //物品的个数
int w[MAXNUM]; //物品i的质量
int v[MAXNUM]; //物品i的价值
int c; //背包的最大承重
int f[MAXNUM];
int main()
{
//freopen("test.in","r",stdin);
scanf("%d",&N);
for (int i=1; i<=N; i++)
scanf("%d%d",&w[i],&v[i]);
scanf("%d",&c);
for (int i=0; i<=c; i++)
f[i]=0;
for (int i=1; i<=N; i++)
for (int j=c; j>=0; j--)
if (j<w[i]) f[j]=f[j];
else f[j]=MAX(f[j], f[j-w[i]]+v[i]);
printf("%d\n",f[c]);
//fclose(stdin);
return 0;
}
二、完全背包问题
(一)问题描述
每个物品有无限多个。问在不超过背包最大承重的情况下,最多能获得多少价值?
(二)代码
</pre><pre name="code" class="cpp">#include <stdio.h>
#define MAXNUM 9999
#define MAX(a,b) a>b?a:b
int N; //物品的个数
int w[MAXNUM]; //物品i的质量
int v[MAXNUM]; //物品i的价值
int c; //背包的最大承重
int f[MAXNUM];
int main()
{
//freopen("test.in","r",stdin);
scanf("%d",&N);
for (int i=1; i<=N; i++)
scanf("%d%d",&w[i],&v[i]);
scanf("%d",&c);
for (int i=0; i<=c; i++)
f[i]=0;
for (int i=1; i<=N; i++)
for (int j=0; j<=c; j++)
if (j<w[i]) f[j]=f[j];
else f[j]=MAX(f[j], f[j-w[i]]+v[i]);
printf("%d\n",f[c]);
//fclose(stdin);
return 0;
}