C语言--01背包问题----二进制枚举法

for(i = 0; i < (1 << type); i++){		//位运算实现所有情况的枚举 
		for(j = 0; j < type; j++){			//依次与每一位是否选取进行比较 
			if(i & (1 << j)){				//如果该情况与某一位对应成功 
				sumv = sumv + obj[j].v;		//价值相加 
				ispace = ispace + obj[j].w;	//体积相加 
			}
		}
		if(sumv > sumvfinal && ispace <= space){	//判定,总价值是否大于上次循环的总价值,体积是否过大 
			sumvfinal = sumv;			//总是将最大的价值赋给sumvfinal 
			choice = i;					//将该种情况取得物体情况赋给choice 
			left = space - ispace;		//算出剩余空间 
		}
		ispace = 0;				//让总体积总价值还原为0,以便再次循环 
		sumv = 0;
	}
	for(i = 0; i < type; i++){	//将choice转换为二进制,确定选了哪几个物体 
		if(choice & (1 << i)){
			names[i] = i + 1;	//如果选择了某个物体,则保存该物体的编号到names[i] 
		}
		else{
			names[i] = 0;		//否则赋值为0,便于输出时判断 
		}

1.枚举法
主要思想是利用二进制0,1判断真假/是否放入,其中涉及到二进制数枚举,位运算&以及移位操作,左移<<

(1)type是物体的种类,1<<type的意思是:将1转换成二进制数,并把1向左移动type位,这实际上是实现了type个2相乘,也就是2^type,然后根据0,1来判断真假的时候,正好有这么些种情况。这样就通过位运算实现了全部情况的枚举。

(2)既然type是物体的种类,那么对于int j<type来说,如果用1来表示是否取得,每一个1<<j其实都表示了第几个种类的物品被取得了,也就是1。

(3)那么,对于每一种情况i,都让他去和所有的1<<j去比对,也就是每种情况下取得的物品情况去和每一个位置的物品去比对,看是否取得,那就用i & (1<<j)去验证,如果不为0,也就是真,那就执行一系列赋值操作,如果为0,也就是没取得,那就进行下一种情况的比对。

(4)&运算:对于&两侧的数字,将其化为二进制数再进行比对,结果也是二进制数,只不过在最后的时候转换为了十进制数。
如果相同位置的数都为1,则结果的对应位置的数也为1,否则结果对应位置的数为0。
比如,对于5&6,那运算中是0000 0101 & 0000 0110 = 0000 0100 = 4。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值