简介:
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取在当前状态下最优或最佳决策的算法。贪心算法基于这样的一个思路:在每一个决策点,我们都选择当前最优的决策,从而希望最终得到一个最优的结果。贪心算法通常用于解决NP完全问题,但是它的正确性并不能保证,因此通常需要其他的算法来验证贪心算法的结果。贪心算法的特点是速度快,实现简单,在某些情况下可以得到比较理想的解。但是,由于贪心算法只关注当前最优解,它不能保证得到全局最优解。因此,在实际应用中,贪心算法需要和其他算法相结合,以得到更加理想的结果。
优点与缺点:
优点:
- 简单易实现:贪心算法只需要在每一步计算当前最优选择,而不需要考虑未来状态,因此实现起来非常简单。
- 时间复杂度低:贪心算法一般具有很好的时间复杂度,这是因为它仅仅需要对当前状态进行一次计算,而不需要对未来状态进行预测。
- 适用范围广:贪心算法可以应用于许多不同的问题,包括图论、数论等多个领域。
缺点:
- 并不一定总是最优:贪心算法仅仅是在当前情况下选择最优的策略,并不能保证得到最优解。
- 没有考虑所有情况:贪心算法仅仅考虑当前状态,并不能对所有情况进行考虑。
- 容易陷入局部最优解:因为贪心算法仅仅考虑当前状态,所以很容易陷入局部最优解,而忽略全局最优解。
贪心算法的原理基于贪心策略:
在对问题的所有的子问题的解进行合并时,总是选择最好的子解。也就是说,贪心算法对每一步的决策都是局部最优的,希望通过局部最优决策的累积得到全局最优解。贪心算法的实现需要确定全局最优解的组成部分,并证明这种决策是全局最优决策。然而,由于贪心算法对每一步决策的选择都是局部最优的,因此不能保证最终得到的解一定是全局最优的。
例题:
有一个背包,容量为V,有n个物品,每个物品有一个体积w[i]和一个价值v[i],问将哪些物品装入背包可使得装入背包中的物品总体积不超过V,且总价值最大。
解决步骤:
1.先将所有物品的价值/体积比进行排序
2.依次选择价值/体积比最大的物品,若装不下则舍弃
3.重复步骤2直到背包装满
代码部分:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
struct node
{
double v;
double w;
double r;
}a[N];
bool cmp(node a, node b)
{
return a.r > b.r;
}
int main()
{
int n, V;
cin >> n >> V;
for (int i = 0; i < n; i++)
{
cin >> a[i].v >> a[i].w;
a[i].r = a[i].v / a[i].w;
}
sort(a, a + n, cmp);
double ans = 0;
for (int i = 0; i < n; i++)
{
if (a[i].w <= V)
{
ans += a[i].v;
V -= a[i].w;
}
else
{
ans += a[i].r * V;
break;
}
}
cout << ans << endl;
return 0;
}