算法思想篇(5)————贪心算法
贪心算法从问题的某一个初始解出发,逐步逼近给定的目标,以便尽快求出更好的解。当达到算法中的某一步不能再继续前进时,就停止算法,给出一个近似解。由贪心算法的特点和思路可看出,贪心算法存在以下3个问题:
(1)不能保证最后的解是最优的;
(2)不能用来求最大或最小解问题;
(3)只能求满足某些约束条件的可行解的范围。
贪心算法的基本思路如下所示。
(1)建立数学模型来描述问题;
(2)把求解的问题分成若干个子问题;
(3)对每一子问题求解,得到子问题的局部最优解;
(4)把子问题的解局部最优解合成原来解问题的一个解。
实现该算法的基本过程如下所示。
(1)从问题的某一初始解出发;
(2)while能向给定总目标前进一步;
(3)求出可行解的一个解元素;
(4)由所有解元素组合成问题的一个可行解。
下面通过一个简单的例子说明一下贪心算法的思想:
用贪心算法实现找零方案,输入要找零的面额,计算出该金额可由哪些面额的人民币组成:
代码如下:
//start from the very beginning,and to create greatness
//@author: Chuangwei Lin
//@E-mail:979951191@qq.com
//@brief: 找零方案
#include <stdio.h>
#define MAXN 9
int parvalue[MAXN]={10000,5000,2000,1000,500,100,50,10};//零钱的面值
int num[MAXN]={0};//零钱各种面值的数量
/******************************************************
函数名:exchange(int n)
参数:找零的金额
功能:找零函数
*******************************************************/
int exchange(int n)
{
int i,j;
for(i=0;i<MAXN;i++) //找到比n小的最大面额
if(n>parvalue[i]) break;//金额是按从大到小排序的,第一个出现n>parvalue[i]就是比n小的最大面额
while(n>0 && i<MAXN)
{
if(n>=parvalue[i])
{
n-=parvalue[i];//减去已找的零钱
num[i]++;//零钱数量加1
}
else if(n<10 && n>0)
{
printf("这里不能找小于1毛的面额哦,采用四舍五入找零");
if (n >= 5)//大于5分就找他1毛
{
num[MAXN-2]++;
}
else//小于5分就不找
num[MAXN-1]++;
break;
}
else //继续找面值更小的零钱
i++;
}
return 0;
}
int main()
{
int i;
float m;//存储欲找零的金额
printf ("输入需要找零金额: " );
scanf("%f",&m);
exchange((int)100*m);//找零
printf("\n%.2f元零钱的组成:\n",m);
for(i=0;i<MAXN;i++)
if(num[i]>0)//如果零钱张数大于1则打印
printf("%6.2f:%d张\n",(float)parvalue[i]/100.0,num[i]);
return 0;
}
运行结果: