0/1背包问题和完全背包问题

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;
} 



二、完全背包问题

(一)问题描述

现有一最大承重c的背包;另有有N件物品,编号为i的物品,重量为wi,所占价值为vi。

每个物品有无限多个。问在不超过背包最大承重的情况下,最多能获得多少价值?

(二)代码

</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;
} 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值