01背包问题真的是最最基础的,完全背包就将01背包的一个循环顺序颠倒了下,多重背包就是在01背包基础上加了一个循环。本文是在学习了《背包九讲》后的总结和实现,感谢大神写的背包指导。(多重背包可以用二进制来表示,不过不是很理解,先贴出最简单的转化为01背包)
01背包
#include<iostream>
using namespace std;
int max(int a,int b)
{
return a>b?a:b;
}
int p[1000]; //p为每个物品的价值
int w[1000]; //w为每个物品的体积
int f[1000]; //最大的总价值
int V; //背包的容积
void zop(int cost,int weight)
{
for(int v=V;v>=cost;v--)
f[v]=max(f[v],f[v-cost]+weight);
}
int main()
{
int n;
cin>>V>>n; //n为物品个数
for(int i=1;i<=n;i++)
{
cin>>w[i];
cin>>p[i];
}
for(i=1;i<=n;i++)
zop(w[i],p[i]);
cout<<f[V]; //求得最大价值
return 0;
}
完全背包
</pre><pre name="code" class="cpp">#include<iostream>
using namespace std;
int max(int a,int b)
{
return a>b?a:b;
}
int p[1000]; //p为每个物品的价值
int w[1000]; //w为每个物品的体积
int f[1000]; //最大的总价值
int V; //背包的容积
void completep(int cost,int weight)
{
for(int v=cost;v<=V;v++)
f[v]=max(f[v],f[v-cost]+weight);
}
int main()
{
int n;
cin>>V>>n; //n为物品个数
for(int i=1;i<=n;i++)
{
cin>>w[i];
cin>>p[i];
}
for(i=1;i<=n;i++)
completep(w[i],p[i]);
cout<<f[V];
return 0;
}
多重背包
#include<iostream>
using namespace std;
int max(int a,int b)
{
return a>b?a:b;
}
int p[1000]; //p为每个物品的价值
int w[1000]; //w为每个物品的体积
int bag[1000]; //第i种背包有n[i]个
int f[1000]; //最大的总价值
int V; //背包的容积
void MultiplePack(int cost,int weight,int n)
{
for(int i=0;i<n;i++) //多一个循环,转化为了01背包问题
{
for(int v=V;v>=cost;v--)
f[v]=max(f[v],f[v-cost]+weight);
}
}
int main()
{
int n;
cin>>V>>n; //n为物品个数
for(int i=1;i<=n;i++)
{
cin>>w[i];
cin>>p[i];
cin>>bag[i];
}
for(i=1;i<=n;i++)
MultiplePack(w[i],p[i],bag[i]);
cout<<f[V];
return 0;
}
咋一看代码都一样,细节之处的差异还是等细心的你去发现。
多重背包个人有个不理解之处:
void MultiplePack(int cost,int weight,int n)
{
for(int i=0;i<n;i++) //多一个循环,转化为了01背包问题
{
for(int v=V;v>=cost;v--)
f[v]=max(f[v],f[v-cost]+weight);
}
}
第一个for为什么是 0 to n-1呢?按照第n个物品有n[i]个,且有n[i]+1种取法,不应该是 0 to n 吗?
望大神指教下~
用以上模板妥妥的完成了hdoj 2191和hdoj 2602,很简单~