14天阅读挑战赛
努力是为了不平庸~
算法介绍
贪心算法(又称贪婪算法) 是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的 局部最优解 。
在实践利用贪心算法求解的问题往往具有两个重要性质:
- 贪心选择: 指原问题的整体最优解可以通过一系列局部最优的选择得到。
- 最优子结构: 即一个问题的最优解包含其子问题的最优解时。
(注:问题最优子结构性质是该问题是否可用贪心算法求解的关键)
贪心算法的基本步骤
基本思路:
- 建立数学模型来描述问题;
- 把求解的问题分成若干个子问题;
- 对每一子问题求解,得到子问题的局部最优解;
- 把子问题的解局部最优解合成原来解问题的一个解。
算法实现:
- 从问题的某个初始解出发。
- 采用循环语句,当可以向求解目标前进一步时,就根据局部最优策略,得到一个部分解,缩小问题的范围或规模。
- 将所有部分解综合起来,得到问题的最终解。
实例分析
找零钱问题
现在店家有1元、5元、10元、50元、100元和500元硬币各c1,c2,c3,c4,c5,c6枚。现在要用这些硬币来给顾客找零钱A元,假设店家找给顾客所需的零钱金额必须是刚刚好,不能多也不能少,最少需要多少枚硬币?
限制条件
0≤ c1,c2,c3,c4,c5,c6≤1000000000
0≤A≤1000000000
依次输入c1,c2,c3,c4,c5,c6和A,以空格分隔,输出最少所需硬币数,如果该金额不能由所给硬币凑出,则返回NOWAY
输入
3 2 1 3 0 2 620
输出
6
问题分析:
需要找零的钱为m,现有零钱种类c1、c2、c3、…cn,每种钱数量无限,如何找到最少的硬币实现找零?
- 限制条件:找的零钱总和等于m;
- 最优函数:硬币数量最少;
- 可行解:要找的钱的组合方式有很多;
- 最优解:找到零钱并且硬币最少。
模板代码:
#include<iostream>
using namespace std;
int main(void){
long long numb[6],A;
int sum=0;
int value[6]={1,5,10,50,100,500};
for(int i=0;i<6;i++)
{
cin>>numb[i];
}
cin>>A;
for (int i = 5; A > 0; i--)
{
int count = numb[i];
int c=0;
if (A > value[i])
{
c = A / value[i];
if (c > count)
{
sum =sum + count;
A =A- count * value[i];
}
else
{
sum =sum+ c;
A =A- c * value[i];
}
}
}
cout<<sum<<endl;
}
测试结果:
3 2 1 3 0 2 620
6
--------------------------------
Process exited after 13.84 seconds with return value 0
请按任意键继续. . .
贪心算法总结
-
适合贪心算法具有的特征:
-
优化问题。
-
问题的求解可以划分为若干阶段。
-
能够制定出最优量度标准。
-
问题具有最优子结构性质。