贪心算法 Problem F 1005 花最少(数量)的纸币

Problem F  Problem ID:1005

简单题意:给出1角、5角、1元、5元、10元的数量,以及想购买的图书价格,在不需要卖家找零的前提下,求出最少需要花多少张纸币以及最多需要花多少张纸币,如果不能实现则输出-1 -1。


解题思路形成过程:求最少需要花多少纸币比较简单:从最大额的纸币开始循环,能用大额的纸币就优先用大额,循环结束即出结果。

      求最多需要花多少纸币则比较麻烦,可以用这样的一个方法:①首先如果求最少花多少纸币时找不到满足条件,则求最多花多少纸币也一定没有满足条件(输出-1 -1)。

        ②求需要最多花多少纸币也就相当于最少留多少纸币,如果设书的总价为m,自己的总钱数为n,n-m则为买书后剩余的钱,使这些剩余的钱的数量(纸币张数)最小化即可,即按照前一个问题(求最少需要花多少纸币)的方式,从最大额纸币开始循环。求出剩余的钱的数量,也就求出了买书花掉的钱的数量,而这个数量正好就是买书所能花费的数量(纸币张数)最大值。


感想:正向想不出来就反向思考一下,很有可能会使问题变得很简单。

PS:代码完全不用那么复杂,每个问题设置一个循环判断即可,但是感觉再写一遍意义不是太大…… 清楚算法就可以了,就懒得再写一遍了TAT

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    while(n--){
        int a[5],b[5];
        memset(a,0,5*sizeof(int));
        memset(b,0,5*sizeof(int));
        int total,total_,cnt1=0,cnt2=0;
        cin>>total;
        total_=total;
        for(int i=0;i<5;++i){
             cin>>a[i];
             b[i]=a[i];
            }

            if(total>=100&&a[4]!=0){    //能用大额的纸币就优先用大额。
                int need;
                need=total/100;
                if(a[4]>=need){
                    cnt1+=need;
                    a[4]-=need;
                    total-=need*100;
                }
                else{
                    cnt1+=a[4];
                    total-=a[4]*100;
                    a[4]=0;
                }
            }
            if(total>=50&&a[3]!=0){
                int need;
                need=total/50;
                if(a[3]>=need){
                    cnt1+=need;
                    a[3]-=need;
                    total-=need*50;
                }
                else{
                    cnt1+=a[3];
                    total-=a[3]*50;
                    a[3]=0;
                }
            }
            if(total>=10&&a[2]!=0){
                int need;
                need=total/10;
                if(a[2]>=need){
                    cnt1+=need;
                    a[2]-=need;
                    total-=need*10;
                }
                else{
                    cnt1+=a[2];
                    total-=a[2]*10;
                    a[2]=0;
                }
            }
            if(total>=5&&a[1]!=0){
                int need;
                need=total/5;
                if(a[1]>=need){
                    cnt1+=need;
                    a[1]-=need;
                    total-=need*5;
                }
                else{
                    cnt1+=a[1];
                    total-=a[1]*5;
                    a[1]=0;
                }
            }
            if(total>=1&&a[0]!=0){
                int need;
                need=total;
                if(a[0]>=need){
                    cnt1+=need;
                    a[0]-=need;
                    total-=need*1;
                }
                else{
                    cnt1+=a[0];
                    total-=a[0]*1;
                    a[0]=0;
                }
            }

        if(total!=0){
            cout<<"-1 -1"<<endl;//如果求最少花多少纸币时找不到满足条件,则求最多花多少纸币也一定没有满足条件(输出-1 -1)。
            continue;}

        int last;
        int num=b[0]+b[1]+b[2]+b[3]+b[4];//钱的总张数。
        last=b[0]+b[1]*5+b[2]*10+b[3]*50+b[4]*100-total_;//买书后剩余的钱。
        if(last>=100&&b[4]!=0){
                int need;
                need=last/100;
                if(b[4]>=need){
                    cnt2+=need;
                    b[4]-=need;
                    last-=need*100;
                }
                else{
                    cnt2+=b[4];
                    last-=b[4]*100;
                    b[4]=0;
                }
            }
        if(last>=50&&b[3]!=0){
                int need;
                need=last/50;
                if(b[3]>=need){
                    cnt2+=need;
                    b[3]-=need;
                    last-=need*50;
                }
                else{
                    cnt2+=b[3];
                    last-=b[3]*50;
                    b[3]=0;
                }
            }
        if(last>=10&&b[2]!=0){
                int need;
                need=last/10;
                if(b[2]>=need){
                    cnt2+=need;
                    b[2]-=need;
                    last-=need*10;
                }
                else{
                    cnt2+=b[2];
                    last-=b[2]*10;
                    b[2]=0;
                }
            }
        if(last>=5&&b[1]!=0){
                int need;
                need=last/5;
                if(b[1]>=need){
                    cnt2+=need;
                    b[1]-=need;
                    last-=need*5;
                }
                else{
                    cnt2+=b[1];
                    last-=b[1]*5;
                    b[1]=0;
                }
            }
        if(last>=1&&b[0]!=0){
                int need;
                need=last;
                if(b[0]>=need){
                    cnt2+=need;
                    b[0]-=need;
                    last-=need*1;
                }
                else{
                    cnt2+=b[0];
                    last-=b[0]*1;
                    b[0]=0;
                }
            }

        cnt2=num-cnt2;
        cout<<cnt1<<' '<<cnt2<<endl;
    }
    return 0;
}
    原文作者:贪心算法
    原文地址: https://blog.csdn.net/q1169917/article/details/50983965
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞