1. 程式人生 > >HUD 1288 Hat's Tea(反向的貪心,非常好的一道題)

HUD 1288 Hat's Tea(反向的貪心,非常好的一道題)

ref miss ssi ret end string man java 都是

傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=1288

Hat‘s Tea

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2127 Accepted Submission(s): 484


Problem Description Hat is a member of PG Studio. Hat codes a lot and so he often buys tea at tea vending machine. But the tea vending machine just eat coins and spit out tea, if you feed the machine more coins than the tea’s price and the machine will not spit out your change.
Your program will be given numbers and types of coins Hat has and the tea price. The tea vending machine accepts coins of values 1, 5, 10 RMB (Jiao). The program should output which coins Hat has to use paying the tea so that he uses as many coins as possible.

Input Each line of the input contains four integer numbers separated by a single space describing one situation to solve. The first integer on the line N, , is the tea price in Jiao. Next four integers , , are the numbers of YiJiao (1 Jiao.RMB), WuJiao (5 Jiao.RMB), and ShiJiao (10 Jiao.RMB) in Hat‘s valet. The last line of the input contains four zeros and no output should be generated for it.

Output For each situation, your program should output one line containing the string " T1 YiJiao, T2 WuJiao, and T3 ShiJiao ", where T1, T2, T3 are the numbers of coins of appropriate values Hat should use to pay the tea while using as many coins as possible. If Hat does not have enough coins to pay the tea exactly, your program should output "Hat cannot buy tea.”.

Sample Input 6653 226 72 352 578 5 127 951 0 0 0 0

Sample Output Hat cannot buy tea. 3 YiJiao, 115 WuJiao, and 0 ShiJiao

Author 戴帽子的

Source 杭電ACM集訓隊訓練賽(VII) 分析: 題目大意呢就是說Hat經常去 自動售茶機去買茶,那麽問題來了: 首先自動售茶機只收硬幣; 然後必須是和其價格等價的硬幣才能夠拿到茶,大於小於都是不可以的; 最後還要求,要多給的硬幣中最多數量的硬幣才能拿到茶;(就是求最多用多少個硬幣能買到茶;) 有兩種方法 第一種是正向的貪心:

首先判斷一些肯定不可能的條件

然後貪心一角硬幣,全部使用一角硬幣。如果剩下的硬幣不是5的倍數。減少一角的使用,使剩下的硬幣成為5的倍數

然後貪心五角硬幣,如果剩下的硬幣不是10的倍數,減少一個五角的使用,如果五角的使用個數為0,減少5個一角的使用個數

如果沒有5個一角的,則不滿足

這種方法,實現起來比較困難,雖然思想簡單,但是要註意的細節太多了

我沒有寫出來。。。

第二種方法:反向的貪心

1角數量*1+5角數量*5+10角數量*10=X

X-茶價格=y

要你求的是用盡可能多的硬幣組成茶價格的值

那麽我用盡可能少的硬幣組成y

那麽剩下的硬幣組成的就是價格呀,且硬幣的數量還是最大的(因為硬幣總數量是確定的)

哈哈哈哈,太聰明了

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
    int v,num1,num5,num10;
    while(~scanf("%d %d %d %d",&v,&num1,&num5,&num10))
    {
        if(v+num1+num5+num10==0)
            break;

        int c1=0,c5=0,c10=0;
        
        
        if(num1+num5*5+num10*10<v)//所有錢加起來都小於價格
        {
            printf("Hat cannot buy tea.\n");
            continue;
        }

        if(num1>=v)//1角的錢就可以滿足價格
        {
            c1=v;
            printf("%d YiJiao, %d WuJiao, and %d ShiJiao\n",c1,c5,c10);
            continue;
        }

        //反著貪心
        //總錢減去價格這個值 用到的錢個數盡可能少 等價於 價格用到的錢個數盡可能多
        int sum=num1+num5*5+num10*10-v;

        //每次都選擇面值最大的,這樣錢的個數就最少
        int x=sum/10;
        if(x>num10)
        {
            sum=sum-10*num10;
             x=0;
        }else
        {
            sum=sum-10*x;
            x=num10-x;
        }

        int y=sum/5;
        if(y>num5)
        {
            sum=sum-5*num5;
            y=0;
        }else
        {
            sum=sum-y*5;
            y=num5-y;
        }

        int flag=1;

        int z=sum;
        if(z>num1)//總錢還小於價格,買不了
        {
            flag=0;
        }else
        {
            sum=sum-z;
            z=num1-z;
        }
        if(flag==0)
        {
            printf("Hat cannot buy tea.\n");
        }else
        {
            printf("%d YiJiao, %d WuJiao, and %d ShiJiao\n",z,y,x);
        }
    }
    return 0;
}

HUD 1288 Hat's Tea(反向的貪心,非常好的一道題)