OJ-1274【逃亡的准备】 DP多重背包练习

 
算是个模板题吧,多重背包的DP+二进制优化
关于多重背包:
1.如果一种物件的数量 足够多(多到背包放不下),那么对于该物件就是做一遍 完全背包
2.否则的话便可以对该物件的每一个做一遍01背包(!)。
这里的二进制优化: (将该物件按 件数 用两个变量将其拆成 若干个2的n次幂 的形式,这样将O(n*n)变为了O(n*log2n))

Code+注释:
 
    

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int F[2086],V[2086],W[2086],Qo[2086],n,C;
void init()
{
cin>>n>>C;
for(int i=1;i<=n;i++)
cin>>Qo[i]>>W[i]>>V[i];
}
int main()
{
ios::sync_with_stdio(false);
init();
memset(F,0,sizeof(F));

for(int i=1;i<=n;i++)
{
if(W[i]*Qo[i]>C)//如果个数乘上单位体积大于背包体积就按完全背包算
{
for(int c=0;c<=C;c++)
if(c>=W[i]) F[c]=max(F[c],F[c-W[i]]+V[i]);
}
else//否则先多重再o1
{
int k=1,amount=Qo[i];
while(k {
for(int c=C;c>=k*W[i];c--)//计算加上一个体积为k*W[i]的物品
F[c]=max(F[c],F[c-k*W[i]]+k*V[i]);
amount-=k;
k+=k;//二进制加!!!
}
for(int c=C;c>=amount*W[i];c--)
F[c]=max(F[c],F[c-amount*W[i]]+amount*V[i]);//01背包加上剩下的来算最优值
}
}
cout< return 0;
}


感觉对于二进制的优化理解又深刻了些。。。星期三再写篇总结吧。

你可能感兴趣的:(题解+注释)