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(没有同一件物品被重复)