算法——背包学习(暂时的总结)

01背包

void ZeroToOne(int weight, int value)

{

         for(int i=maxV; i>=weight; i--){

                   bag[i]= max(bag[i], bag[i-weight]+value);

         }

}

 

 

 

         完全背包

void CompleteBag(int weight, int value)

{

         for(int i=weight; i<=maxV; i++){

                   bag[i]= max(bag[i], bag[i-weight]+value);

         }

}

 

 

 

         多重背包

void MultipleBag(int num, int weight, intvalue)

{

         if( num*weight>=maxV ){

                   CompleteBag(weight,value);

                   return;

         }

 

         intk = 1;

         while( k<num )

         {

                   ZeroToOne(weight*k,value*k);

                   num-= k;

                   k*= 2;

         }

         ZeroToOne(weight*num,value*num);

}

以上为三种最基础的背包,其他绝大部分都是由此演化而来

 

 

         分组背包

凡是物品间有相互关系的都可以当做分组背包,多变

每组最多取一个:把同一组的物品视为并列的物品,在同一层上进行背包(hdu1712)

每组至少取一个:增加一条选择路径:上一组完成的背包+当前物品(hdu3033)

 

 

 

         01背包最优解个数(hdu2126)

用bag数组存最优解,同时num数组存最优解个数

 

 

 

         01背包第K优解(hdu2639)

用bag[v][n]更新花费v以内的前n个解

 

 

 

         01背包花费为负数(poj2184)

花费为负时,v-cost>v(每个v由v-cost与自身比较),所以当花费为负从小到大遍历

花费为正时,同普通01背包,从大到小遍历

 

 

 

         01背包花费为double(poj2184)

将花费与价值对调后进行背包,逆向思维

 

 

 

         状压+01背包(poj2923)

将所有可能的状态进行状压存储,以这些状态为花费进行背包,花费判断为:v&sig==0(没有同一件物品被重复)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值