问题描述
题目分析
这个问题和0-1背包问题有一定的差别,0-1背包问题的解决方法可以参加我的另一篇文章0-1背包问题
这两类问题都具有最优子结构性质。对0-1背包问题,设A是能够装入容量为c的背包的具有最大价值的物品集合,则为Aj = A-{j}是n-1个物1,2,…j-1,j+1…n可装入容量为c-wj的背包的具有最大价值的物品集合。对于背包问题,类似地,若它的一个最优解包含物品j,则从该最优解中拿出所含物品j的那部分重量w,剩余的将是n-1个原重物品1,2,…,j-1,j+1,…,n及重为wj-w的物品j中可装入容量为c-w的背包且具有最大价值的物品。
虽然这两个问题极为相似,但背包问题可以通过贪心算法解决求解,而0-1背包问题不能用贪心算法求解。用贪心算法解背包问题的基本步骤是:首先计算每种物品单位重量的夹着vi/wi;然后依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过c,则选择单位重量价值次高的物品并尽可能多地装入背包。以此策略,一直进行下去,直到背包装满为止。
代码
#include <iostream>
#include <fstream>
#include <windows.h>
#include <iomanip>
#include <stdlib.h>
#include <ctime>
#include <algorithm>
using namespace std;
struct Goods{
int w,v;
double p;
};
void Random(){//随机产生物品的重量和价值
srand(time(0));
ofstream output("input1.txt");
cout<<"请输入背包的重量和商品的件数:";
int c,n;
cin>>c>>n;
output<<c<<" "<<n<<endl;
for(int i=0;i<n;i++){
int w=rand()%(c-1+1)+1;
int v=rand()%(c-1+1)+1;
output<<w<<" "<<v<<endl;
}
}
bool com(Goods a,Goods b){
return a.p>b.p;
}
int main(){
Random();
ifstream input("input1.txt");
if(!input)
cout<<"打开失败!";
ofstream output("output1.txt");
int c,n;
input>>c>>n;
Goods goods[n+1];
for(int i=1;i<=n;i++)
{
input>>goods[i].w>>goods[i].v;
goods[i].p=double(goods[i].v)/double(goods[i].w);
}
/* for(int i=1;i<=n;i++)
cout<<"第"<<i<<"件商品的单价是:"<<goods[i].p<<endl; */
LARGE_INTEGER BegainTime;
LARGE_INTEGER EndTime;
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
QueryPerformanceCounter(&BegainTime) ;
sort(goods+1,goods+n+1,com);
int k=1;
double sum=0;
while(c>0&&k<=n){
if(goods[k].w<=c){
sum+=goods[k].v;
c-=goods[k].w;
}
else{
sum+=goods[k].p*c;
}
k++;
}
cout<<"能获得的最大价值是:"<<fixed << setprecision(0)<<sum<<endl;
output<<"能获得的最大价值是:"<<fixed << setprecision(0)<<sum<<endl;
QueryPerformanceCounter(&EndTime);
cout<<"运行时间:"
<<fixed << setprecision(0)<<(double)(EndTime.QuadPart-BegainTime.QuadPart)
<<"us"<<endl;
output<<"运行时间:"
<<fixed << setprecision(0)<<(double)(EndTime.QuadPart-BegainTime.QuadPart)
<<"us"<<endl;
/* for(int i=1;i<=n;i++)
{
for(int j=0;j<=c;j++)
cout<<B[i][j]<<" ";
cout<<endl;
} */
}
总结
时间复杂度主要取决我们使用什么样的排序算法,最好的是O(nlogn)