您的位置:首页 > 其它

problemF

2016-03-29 22:20 190 查看
简单题意:一堆零钱去买东西,要求正好付钱,求最少的零钱数和最多的零钱数

解题思路:求最小零钱数的时候,要让价值大的多一些,然后用价值小的去补,求最大的零钱数 要尽量用小面值的,然后再用大面值的补;

感想:这题和背包问题有些相似,都是用贪心的算法,用价值去算

AC代码:

#include <stdio.h>

#include <string.h>

#include <algorithm>

#include <math.h>

#include <sstream>

#include <vector>

#include <stack>

#include <map>

#include <queue>

#include <set>

#include <iostream>

#include <stdlib.h>

#include <cctype>

#define rep(i,s,e) for(int i = (s);i<(e);++i)

#define maxn 200000000

#define INF 1000000000

using namespace std;

int num[10];

int sum[10];

int mon[] = {0,1,5,10,50,100};

int p;

int min_num(int mon[],int num[],int p)

{

    int ans = 0;

    for(int i = 5;i>1;--i)

    {

        if(mon[i]*num[i]<=p)

        {

          ans += num[i];

          p -= num[i]*mon[i];

        }else

        {

            ans += p/mon[i];

            p%=mon[i];

        }

    }

    if(p<=num[1])

    return p+ans;

    return -1;

}

int max_num(int mon[],int num[],int sum[],int p)

{

    int ans = 0;

    for(int i =5;i>1;--i)

    {

        if(p<=sum[i-1])

        continue;

        else

        {

            int t = (p - sum[i-1])/mon[i];

            if((p - sum[i-1])%mon[i]!=0)

            t++;

            ans += t;

            p -= t*mon[i];

        }

    }

    if(p<=num[1])

    {

        return ans + p;

    }

    return -1;

}

int main()

{

   

    int t;

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d",&p);

        int Sum = 0;

        for(int i = 1;i<=5;++i)

        {

            scanf("%d",&num[i]);

            Sum += num[i]*mon[i];

        }

        if(Sum < p)

        {

            cout<<-1<<" "<<-1<<endl;

            continue;

        }

        sum[0] = 0;

        for(int i =1;i<=5;++i)

        sum [i] = sum[i-1]+num[i]*mon[i];

       

        cout<<min_num(mon,num,p)<<" "<<max(-1,max_num(mon,num,sum,p))<<endl;

    }

    return 0;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: