枚举法解决一切 0--1背包问题

一.当3个物品数量,总背包为40时      每个物品重量 10 20 30    价值为  70 80 150 

 代码如下:

#include<stdio.h>
#define n 3
possible_solution(int x[n]){
	int i;
	for(i=0;i<3;i++)
	  if(x[i]!=1) { x[i]=1;return;}
	  else   x[i]=0;
	  return;
}
int main(){
	int w[n]={10,20,30},v[n]={70,80,150};
	int x[n]={0,0,0},y[n]={0,0,0};
	int tw,tv,tv1=0,limit=40;
	int j;
	for(j=1;j<=8;j++){
		possible_solution(x);
		tw=x[0]*w[0]+x[1]*w[1]+x[2]*w[2];
		tv=x[0]*v[0]+x[1]*v[1]+x[2]*v[2];
		if(tw<=limit&&tv>tv1){
			tv1=tv; y[0]=x[0];y[1]=x[1];y[2]=x[2];
		}
	}
	printf("0-1背包问题的最优解 y=(%d,%d,%d)\n",y[0],y[1],y[2]);
	printf("总价值为:%d",tv1);
}

通过此代码过程,可以给出通用的枚举法解决所有背包问题

代码如下:

#include<stdio.h>
#include<math.h>
int n; 
int fun(int x[n]){
	int i;
	for(i=0;i<n;i++) 
	   if(x[i]!=1)  {x[i]=1; return;}
	   else x[i]=0;
	   return;
}

int main(){
    int w[100],v[100];
	int x[100]={0},y[100]={0};
	int tv=0,tv1=0,tw=0,i,j,limit;
	printf("请输入多少数量:"); 
	scanf("%d",&n);
	printf("请输入背包的容量:");
	 scanf("%d",&limit); 
	 printf("输入每个产品的重量:"); 
	for(i=0;i<n;i++)
		scanf("%d",&w[i]);
	  printf("输入每个产品的价值:");
	for(i=0;i<n;i++)
	    scanf("%d",&v[i]);
	for(j=1;j<=pow(2,n);j++){
		fun(x);
		for(i=0;i<n;i++){
			tw+=w[i]*x[i];
			tv+=v[i]*x[i];
		}
		if(tw<=limit&&tv>tv1){
			tv1=tv;    
			for(i=0;i<n;i++){
				y[i]=x[i];		
			}
		}
		tw=0;
		tv=0;
	}
	printf("0-1背包问题的最优解为:");
	  for(i=0;i<n;i++)  printf("%d ",y[i]);
	  printf("\n总价值为:%d",tv1);	
}

神来之笔:

int fun(int x[n]){
	int i;
	for(i=0;i<n;i++) 
	   if(x[i]!=1)  {x[i]=1; return;}
	   else x[i]=0;
	   return;
}

这个代码可以直接取每个商品的数量是0还是1,要是我写的话,可能用几个for循环遍历0和1吧。

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值