算法学习(二)贪婪算法

1.1引言

    贪婪算法,基本思路就是不求最优解,而只希望得到较为满意解的一种方法,通过贪婪算法,一般可以快速的得到满意的解。因为它省去了要求最优解而去穷举所有可能的步骤,贪婪算法的特点是,通过做局部的最优选择而达到全局的最优情况。

1.2 算法思路

    贪婪算法基本思路:从问题的某一个初始解出发,逐步的逼近给定的目标,以尽可能地求得更好的解。当达到算法的某一步不能再继续前进时,就停止算法,给出近似解。

    由于贪婪算法的特点和思路可以看出,该算法存在以下的问题:

    1. 不能保证最后的解是最优的;

    2. 不能用来来最大或最小解问题;

    3. 只能求满足某些约束条件的可行解的范围;  

1.3 实例:换零钱问题

    设人民币有100,50,10,5,2,1,0.5,0.2,0.1等多种面额(单位为元)。在补零钱时,可有多种方案,例如需要补充零钱68.90元,至少可有以下方案:

    - 1张50, 1张10, 1张5, 3张1, 1张0.5, 2张0.2;

    - 1张50, 1张10, 1张5, 3张1, 1张0.5, 4张0.1;

    - 6张10, 1张5, 3张1, 1张0.5, 2张0.2;


  程序中,我们输入要找取零钱的金额,然后由程序算出需要有哪些人民币的金额来构成。

    

#include <stdio.h>
#include <conio.h>

#define Max 9 //定义有九种面额的人民币
/*
定义每种面额的人民币金额,
考虑到使用整数计算更为方便,
我们就将以分为单位进行计算
*/
int parvalue[Max] ={10000,5000,1000,500,200,100,50,20,10};
int num[Max]={0}; //保存对应面额的人民币的张数
//例: 如果找的100元有一张,即为num[0]=1;
int exchange(int n)
{ //n表示需要补给顾客的钱的数量
int i,j;
for(i=0;i<Max;i++)
if(n>parvalue[i]) break; //找到比n小的最大面额
while(n>0&&i<Max)
{
if(n>=parvalue[i])
{
n-=parvalue[i];
num[i]++;
}else if(n<10 && n>=5) //最后大于5分而小于10分
{
num[Max-1]++;
break;
}else i++;
}
return 0;
}
int main()
{
int i;
float m;
printf("请输入找零的金额:");
scanf("%f",&m); //float,单精度浮点型,对应%f.
exchange((int)100*m);
printf("\n%.2f元零钱的组成:\n",m);
for(i=0;i<Max;i++)
if(num[i]>0)
//位数总共为6位,保留两位小数
printf("%6.2f:%d张\n",(float)parvalue[i]/100.0,num[i]);
getch();
return 0;
}




   楼主在书上讲的贪心算法中发现,书上的很多贪心算法用到了动态规划的思路,这里只是第一篇,楼主会时常更新,看官们稍安勿躁了