1、基本思路:从问题的某一个初始解触发逐步逼近给定的目标,以尽可能快的求得更好的解。当达到算法中某一步不能再继续前进时,就停止算法,给出近似值。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
存在的问题:
1、不能保证最后的解是最优的;
2、不能用来求最大或最小解的问题;
3、只能求满足某些约束条件的可行解的范围。
实现过程:
从问题的某一初始解出发;
while (能朝给定总目标前进一步)
{
利用可行的决策,求出可行解的一个解元素;
}
由所有解元素组合成问题的一个可行解;
贪心算法的基本要素:(对于一个具体的问题,怎么知道是否可用贪心算法解此问题)
(1)、贪心选择性质
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。
对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
(2)、最优子结构性质
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。
实例:换零钱
人民币100、50、20、10、5、1、0.5、0.2、01多种纸币。将一定数额的钱数用不能面额组合起来。
代码:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
#include<iostream>
const int SIZE = 9;
int coin[SIZE] = {10000, 5000, 2000, 1000, 500, 100, 50, 20, 10};
int num[SIZE];
int exchange(int n);
int main()
{
using namespace std;
double money;
string name[SIZE] = {"一百元", "五十元", "二十元", "十元", "5元", "1元", "5角", "2角", "1角"};
cout << "请输入金额:";
cin >> money;
int n = (int)(money*100);
exchange(n);
for(int i=0; i<SIZE; i++)
{
cout << name[i] << "币种: " << num[i] << " 张\n";
}
return 0;
}
int exchange(int n)
{
int i;
for (i=0; i<SIZE; i++)
if (n >= coin[i]) break;
while (n>0 && i<SIZE)
{
if(n >= coin[i])
{
n -= coin[i];
num[i]++;
}else if(n<10 && n>=5)
{
num[SIZE-1]++;
break;
}else i++;
}
return 0;
}