首页 > 其他 > 详细

背包问题系列

时间:2021-08-08 11:09:43      阅读:17      评论:0      收藏:0      [点我收藏+]

背包问题

0/1背包问题

题目:

  • 给定n种物品和一个容量为c的背包,物品i的重量是 wi,其价值为vi。问︰应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?

问题分析:

  • 面对每个物品,我们只有选择拿或者不拿两种选择,不能选择装入某物品的一部分,也不能装入同一物品多次。
  • 0/1背包问题中的0代表这个物品不拿,1代表这个物品拿。是一个拿与不拿的问题。

例题及输入输出:

技术分享图片

例题的动态规划(DP)

w[i] c[i] 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0 0
2 1 0 0 1 1 1 1 1 1 1 1 1
3 3 0 0 1 3 3 4 4 4 4 4 4
4 5 0 0 1 3 5 5 6 8 8 9 9
7 9 0 0 1 3 5 5 6 9 9 10 12

例题代码

//0/1背包问题 
#include<stdio.h> 
#include<stdlib.h>
int dp[35][205];
int w[35],c[35];

int max(int a,int b)
{
	if(a>=b){
		return a;
	}
	return b;
}

int main()
{
	int i=0,j=0;
	int m,n;//m代表背包容量,n代表物品数量 
	printf("请输入m和n的值:\n");
	scanf("%d",&m);
	scanf("%d",&n);
	for(i=1;i<=n;i++){//键盘输入物品重量的数组 
		scanf("%d",&w[i]);
	} 
	for(i=1;i<=n;i++){//键盘输入物品价值的数组 
		scanf("%d",&c[i]);
	} 
	//dp表的计算算法部分 
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			if(j<w[i]){
				dp[i][j]=dp[i-1][j];
			}else{
				dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+c[i]);
			}
		}
	}
	//输出dp表 
	printf("dp表如下所示:\n");
	for(i=0;i<=n;i++){
		for(j=0;j<=m;j++){
			printf("%-3d",dp[i][j]);
		}
		printf("\n");
	}
	
	printf("背包能放入的最大价值为:%d\n",dp[n][m]);
	return 0;
}

完全背包问题

例题及输入输出:

技术分享图片

例题的动态规划(DP)

w[i] c[i] 0 1 2 3 4 5 6 7 8 9 10
0 0 0 0 0 0 0 0 0 0 0 0 0
2 1 0 0 1 1 2 2 3 3 4 4 5
3 3 0 0 1 3 3 4 6 6 7 9 9
4 5 0 0 1 3 5 5 6 8 10 10 11
7 9 0 0 1 3 5 5 6 9 9 10 12

例题代码

//完全背包问题
//化简前写法 
#include<stdio.h>
#include<stdlib.h>

int w[50],c[50],dp[210]; 

int max(int x,int y)
{
	if(x>y){
		return x;
	}
	return y;
}

int main()
{
	int m,n;
	int i=0,j=0,k=0;
	printf("请输入m和n的值:\n");
	scanf("%d",&m);
	scanf("%d",&n);
	printf("请输入w[i]数组的值:\n");
	for(i=1;i<=n;i++){
		scanf("%d",&w[i]);
	}
	printf("请输入c[i]数组的值:\n");
	for(i=1;i<=n;i++){
		scanf("%d",&c[i]);
	}
	for(i=1;i<=n;i++){
		for(j=m;j>=1;j--){
			for(k=0;k<=j/w[i];k++){
				dp[j]=max(dp[j],dp[j-k*w[i]]+k*c[i]);
			}
		}
	}
	
	printf("%d",dp[m]);
	return 0;
} 

多重背包问题

题目:

  • 有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

问题分析:

  • 我们仔细观察题目,会发现不同点在于每种物品的数量,01背包是每种只有1件,完全背包是每种无限件,而多重背包是每种有限件。

例题及输入输出:

技术分享图片

例题代码

#include<stdio.h>
#include<stdlib.h> 

int max(int x,int y)
{
	if(x>y){
		return x;
	}
	return y;
}

int v[510],w[510],s[510],dp[6100];//v数组代表价格,w数组代表价值,s数组代表数量 

int main()
{
	int n,m;
	int i,j,k;
	printf("请输入n和m的值:\n");
	scanf("%d",&n);
	scanf("%d",&m);
	for(i=1;i<=n;i++){
		scanf("%d",&v[i]);
		scanf("%d",&w[i]);
		scanf("%d",&s[i]);
	}
	
	for(i=1;i<=n;++i){
		for(j=m;j>=1;--j){
			for(k=0;k<=s[i]&&k*v[i]<=j;++k){
				dp[j]=max(dp[j],dp[j-k*v[i]]+k*w[i]);
			}
		}
	}
	
	printf("%d",dp[m]);
	
	return 0;
} 

背包问题系列

原文:https://www.cnblogs.com/rosy1203/p/15114213.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!