完全背包问题
问题重述
有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。第 i 种物品的体积是 vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤1000
0<vi,wi≤1000
思路分析:
回顾我们的01背包问题,完全背包问题01背包问题的区别在于01背包的物品只有一件,只有选与不选的问题,而完全背包每件物品有无数件我们需要考虑选与不选,选的话还要考虑选几件的问题。相较于01背包貌似一下子麻烦了许多。但其实如果我们对优化后的01背包代码理解透彻话,只要改动一个地方就是此题的解,即循环体积时从小到大开始即可。
C++代码:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int i,j,N,V;
int volume,value;
vector<int>ans;
cin>>N>>V; //输入物品数与背包体积
ans.resize(V+10,0);//开辟合适的空间
for(i=0;i<N;i++) //开始循环物品
{
cin>>volume>>value; //现场输入当前物品属性
for(j=volume;j<=V;j++) //体积循环与01背包相反从小到大
{
ans[j]=max(ans[j],ans[j-volume]+value);//状态转移方程
}
}
cout<<ans[V]<<endl;
return 0;
}
解释:
为什么体积从小开始就可以了呢?我们可以这样想因为每件物品都有无数件,所以我们可以随意放几件,我们应该找到放几件最合适,那从物品体积到背包体积遍历就是一个尝试放几件最好的过程每次我们都为这件物品留出它的空间来放一下他看看是不是可以增加价值,如果能增加当体积增加后我们再拿一件这个物品留出空间放进去,以此我们就能找到放几件这个物品最为合适。