转自:https://blog.csdn.net/qq_34624515/article/details/84583149
问题描述:
假设山洞里有 n 种宝物,每种宝物有一定重量 w 和相应的价值 v ,毛驴运载能力有限,只能运走 m 重量的宝物,
一种宝物只能拿一样,宝物可分割。那么如何使毛驴运 走最大价值的宝物?
问题分析:
物品可分割的装载问题为背包问题,物品不可以分割的装载问题为0-1背包问题
【思考过程】
如果选价值量最大的宝物,那重量不一定小,不行;
如果选重量最小的宝物,那价值不一定高,也不行;
每次选取单位重量价值最大的宝物,即每次选择性价比(价值/重量)最高的宝物,达到运载重量 m ,那一定是价值最大的。
【算法设计】
(1)数据结构及初始化。将 n 种宝物的重量和价值存储在结构体 three(含重量、价值、性价比),按性价比从高到底排序。
用 sum 来存储毛驴能够运走的最大价值,初始量为 0。
(2)根据贪心策略,按性价比从大到小选宝物,直到达到毛驴的运载能力。每次选性价比高的物品,判断是否小于 m ,若小于则放入,
sum加上当前宝物的价值,m减去当前宝物的重量;若大于,则取该宝物的一部分 m*p[i] , m=0 ,程序结束。m减少到0,则sum得到最大值。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN=10000; 4 double sum=0.0; //记录贪心选择宝物的价值之和 5 struct three{ 6 double w; //每个宝物的重量 7 double v; //每个宝物的价值 8 double p; //性价比=价值/重量 9 }s[MAXN]; 10 bool cmp(three a,three b){ //定义sort的比较类型,按照宝物性价比降序 11 return a.p>a.p; //按照性价比降序排列sort(s,s+n,cmp) 12 } 13 int main(){ 14 int n; //宝物的数量 15 double m; //能运走 m 重量的宝物 16 cin>>n>>m; 17 for(int i=0;i<n;i++){ 18 cin>>s[i].w>>s[i].v; //读入宝物重量和价值 19 s[i].p=s[i].v/s[i].w; 20 } 21 sort(s,s+n,cmp); 22 for(int i=0;i<n;i++){ 23 if(m>s[i].w){ //宝物重量小于承载能力则可以选择 24 m-=s[i].w; 25 sum+=s[i].v; 26 }else{ 27 sum+=m*s[i].p; //不足装入整个宝物,部分装入 28 break; 29 } 30 } 31 cout<<sum<<endl; 32 return 0; 33 }
有问题的代码
经学长改进后:
1 // main.cpp 2 // demo 3 // 4 // Created by MYL on 2020/2/29. 5 // Copyright 2020 马英粼. All rights reserved. 6 // 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <vector> 11 using namespace std; 12 const int maxn = 1e5+10; 13 struct good{ 14 double w, v, xingjiabi; //重量和价值 15 } goods[maxn]; 16 int n, weight; 17 double ans; 18 bool cmp (good a, good b) { 19 return a.xingjiabi > b.xingjiabi; 20 } 21 int main(int argc, const char * argv[]) { 22 cin >> n >> weight; 23 for (int i = 1; i <= n; i++) { 24 cin >> goods[i].w >> goods[i].v; 25 goods[i].xingjiabi = goods[i].v / goods[i].w; 26 } 27 sort(goods+1, goods+1+n, cmp); 28 int cnt = 1; 29 while (weight) { 30 if (goods[cnt].w <= weight) { 31 ans += goods[cnt].v; 32 weight -= goods[cnt].w; 33 cnt++; 34 continue; 35 } else { 36 ans += weight * goods[cnt].xingjiabi; 37 weight = 0; 38 } 39 } 40 cout << ans; 41 return 0; 42 }
感谢大佬QAQ