大家好,欢迎来到IT知识分享网。
题目
有一个背包,背包容量是M=150。有7个物品,物品可以分割成任意大小。
要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。
思路
具有最优子结构性质和贪心选择性质。只要是所有物品的总重量大于背包容纳量,那么背包一定能装满。注意背包问题与0-1背包问题的区别。
这2类问题都具有最优子结构性质,极为相似,但背包问题可以用贪心算法求解,而0-1背包问题却不能用贪心算法求解。
求解步骤
用贪心算法解背包问题的基本步骤:首先计算每种物品单位重量的价值v[i]/w[i],然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直地进行下去,直到背包装满为止。
代码实现
#include <iostream>
using namespace std;
//按照单位重量的价值量大小降序排列
void Sort(int n,float *w,float *v)
{
int i,j;
float temp1,temp2;
for(i=1;i<=n;i++)
for(j=1;j<=n-i;j++)//冒泡排序
{
temp1=v[j]/w[j];
temp2=v[j+1]/w[j+1];
if(temp1<temp2)
{
swap(w[j],w[j+1]);
swap(v[j],v[j+1]);
}
}
}
int main()
{
float w[101];//用来表示每个物品的重量
float v[101];//用来表示每个物品的价值量
float x[101];//表示最后放入背包的比例
int n;//物品数
float M;//背包最大容纳重量
cin>>n>>M;
//依次输入每件物品的重量和价值量
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
//按照单位重量的价值量大小降序排列
Sort(n,w,v);
int i;
for(i=1;i<=n;i++)
x[i]=0;//初始值,未装入背包,x[i]=0
float c=M;//更新背包容纳量
for(i=1;i<=n;i++)
{
if(c<w[i]) break;//不能完全装下
x[i]=1;
c=c-w[i];
}
if(i<=n)
x[i]=c/w[i];
//输出
for(int i=1;i<=n;i++)
cout<<"重量为"<<w[i]<<"价值量为"<<v[i]<<"的物品"<<"放入的比例为"<<x[i]<<endl;
return 0;
}
算的主要计算时间在于将各种物品依其单位重量的价值从大到小排序。因此,算法的计算时间上界为O(nlogn)。
为了证明算法的正确性,还必须证明背包问题具有贪心选择性质。
对于0-1背包问题,贪心选择之所以不能得到最优解是因为在这种情况下,它无法保证最终能将背包装满,部分闲置的背包空间使每公斤背包空间的价值降低了。事实上,在考虑0-1背包问题时,应比较选择该物品和不选择该物品所导致的最终方案,然后再作出最好选择。由此就导出许多互相重叠的子问题。这正是该问题可用动态规划算法求解的另一重要特征。
实际上也是如此,动态规划算法的确可以有效地解0-1背包问题。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/15967.html