贪心算法解决问题

贪心算法

描述:

贪心算法也叫作贪婪算法,是指在求解问题时总做出在当前看来最好的选择,就是不从整体考虑问题,仅在某种意义上的局部最优解。虽然不是所有问题都能得到最优解,但是面对范围广泛的许多问题时,能产生整体最优解或者是整体最优解的近似值。

贪心算法思路:

从问题的某一个初始解出发,逐步逼近给定的目标,以便更快的求出更好的解。当达到算法中某一步不能再向前时,就停止算法,给出一个近似解。

缺点:

(1)不能保证最后的解是最优解;
(2)不能用来求最大、最小解问题;
(3)只能求满足某些约束条件的可行解范围。

矩阵选数问题

在N行M列的正整数矩阵中,要求从每行中选出1个数,使得选出的总共N个数的和最大。(1<=N, M<=100,结果在int范围内)

【分析】要使总和最大,则每个数要尽可能大,自然应该选每行中最大的那个数。

    局部最优解:每行中的最大数;全局最优解:N个数和的最大值。
#include <stdio.h>  
#define maxn 105  
int N,M;  
int maxnum;   //maxnum记录每行中的最大值  
int sum=0;    //sum记录每行中的最大值之和   
int a[maxn][maxn];  
int main()  
{  
    int i,j;  
    scanf("%d %d",&N,&M);  
    for(i=0;i<N;i++)  
        for(j=0;j<M;j++)  
            scanf("%d",&a[i][j]);  
    for(i=0;i<N;i++)  
    {  
        maxnum=0;      
        for(j=0;j<M;j++)   //循环更新每行的最大值   
        {  
            if(a[i][j]>maxnum)  
                maxnum=a[i][j];  
        }  
        sum+=maxnum;   
    }  
    printf("%d\n",sum);  
    return 0;  
}  
钱币找零问题

有1元、5元、10元、50元、100元、500元的硬币各C1, C5, C10, C50, C100, C500枚。现在要用这些硬币来支付A元,最少需要多少枚硬币?若有解,输出最少硬币数;否则输出“-1”(0<=C1, C5, C10, C50, C100, C500<=109,0<=A<=109)

【分析】凭直觉,我们可以优先使用面值大的硬币(在这里是500、100、50、10、5、1)

#include <iostream>  
using namespace std;  
int A;   
int ans=0;      //所需硬币总数  
int ret[6]={0}; //所需每种硬币的数量   
int moneycnt[6];//现有6种硬币的数量   
int moneyval[6]={1,5,10,50,100,500};//每种硬币的面值   
int main()  
{  
    int i;  
    int temp;  
    cin>>A;  
    for(i=0;i<6;i++)  
        cin>>moneycnt[i];  
    //贪心策略:优先选择面值大的硬币   
    for(i=5;i>=0;i--)  
    {  
        //temp记录使用硬币i的枚数,注意不能超过moneycnt[i]   
        temp=min(A/moneyval[i],moneycnt[i]);   
        //剩余支付金额   
        A-=(temp*moneyval[i]);  
        //使用硬币i的枚数+temp   
        ret[i]+=temp;  
        //已使用的硬币数+temp   
        ans+=temp;             
    }   
    //A>0表示无法用现有硬币支付A元,故输出-1   
    if(A>0)  
        cout<<"-1"<<endl;  
    //其它情况:可完成支付   
    else  
    {  
        //最少硬币数   
        cout<<ans<<endl;  
        //每种硬币需要的数量   
        for(i=0;i<6;i++)  
            cout<<moneyval[i]<<"元:"<<ret[i]<<endl;  
    }  
    return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

askunix_hjh

谢谢请我吃糖~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值