贪心法介绍: 一个贪心算法总是做出当前最好的选择,也就是说,它期望通过局部最优选择从而得到全局最优的解决方案。
大体步骤:
- 贪心策略:制定贪心策略,并选择最佳的策略实施
- 局部最优解:通过策略,一步一步得到局部最优解。
- 全局最优解:把所有的局部最优解整合到一起,还原出原来问题的最优解。
示例如下
问题描述
假设山洞中有n种宝物,每种宝物有一定重量w和相应的价值v,毛驴运载能力有限,只能运走m重量的宝物,一种宝物只能拿一样,宝物可以分割。那么怎么才能让背包装走宝物的价值最大呢?
贪心策略
- 每次挑选价值最大的宝物装入背包,得到的结果是否为最优?
- 每次挑选重量最小的宝物装入背包,得到的结果是否为最优?
- 每次挑选价值单位重量价值最大的宝物装入背包,得到的结果是否为最优?
分析各策略后,我们挑选第三种策略:每次挑选价值单位重量价值最大的宝物装入背包。
思路
- 计算每件宝物的性价比
- 将宝物按性价比排序
- 按贪心策略依次将性价比最高的宝物放入背包
- 若是下一性价比最高宝物重量超过剩余背包容量,将宝物拆分后再放入背包
完整代码
#include<iostream>
#include<algorithm>
using namespace std;
const int M = 10005;
struct three
{
double w; // 宝物重量
double v; // 宝物价值
double p; // 宝物性价比
}s[M];
bool cmp(three a,three b)
{
// 按照宝物的性价比排序
return a.p > b.p;
}
int main()
{
int n; // 宝物数量 n
double m; // 背包的最大载重 m
cout << "请输入宝物数量 n 及背包的最大载重 m " << endl;
cin >> n >> m;
cout << "请输入每个宝物的重量 w 及价值 v " << endl;
for(int i = 0;i < n;i++)
{
cin >> s[i].w >> s[i].v;
// 求性价比
s[i].p = s[i].v / s[i].w;
}
// 按性价比排序
sort(s, s+n,cmp);
// 装入的宝物的最大价值总和
double sum = 0.0;
// 将宝物装入背包
for(int i=0;i<n;i++)
{
if(m > s[i].w)
{
m -= s[i].w;
sum += s[i].v;
}
else
{
sum += (m*s[i].p);
break;
}
}
cout << "装入的宝物的最大价值总和为" << sum << endl;
return 0;
}
来源:CSDN
作者:莫莫先生
链接:https://blog.csdn.net/weixin_44835732/article/details/103638119