Too Rich HDU - 5527 (思维题+贪心)
2017-06-14 10:49
423 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5527
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1253 Accepted Submission(s): 299
Problem Description
You are a rich person, and you think your wallet is too heavy and full now. So you want to give me some money by buying a lovely pusheen sticker which costs pdollars
from me. To make your wallet lighter, you decide to pay exactly p dollars
by as many coins and/or banknotes as possible.
For example, if p=17 and
you have two $10 coins,
four $5 coins,
and eight $1 coins,
you will pay it by two $5 coins
and seven $1 coins.
But this task is incredibly hard since you are too rich and the sticker is too expensive and pusheen is too lovely, please write a program to calculate the best solution.
Input
The first line contains an integer T indicating
the total number of test cases. Each test case is a line with 11 integers p,c1,c5,c10,c20,c50,c100,c200,c500,c1000,c2000,
specifying the price of the pusheen sticker, and the number of coins and banknotes in each denomination. The number ci means
how many coins/banknotes in denominations of i dollars
in your wallet.
1≤T≤20000
0≤p≤109
0≤ci≤100000
Output
For each test case, please output the maximum number of coins and/or banknotes he can pay for exactly p dollars
in a line. If you cannot pay for exactly p dollars,
please simply output '-1'.
Sample Input
3
17 8 4 2 0 0 0 0 0 0 0
100 99 0 0 0 0 0 0 0 0 0
2015 9 8 7 6 5 4 3 2 1 0
Sample Output
9
-1
36
Source
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)
题目大意:某人在钱包中有面值为1,5,10,20,,等的硬币分别为num[i]张。然后要这个人要付款p元,问恰好能凑成这p元所需要的最多的硬币的张数,如果不能准确的凑成p元输出-1。
题解:首先想到的就是用贪心,先考虑花小面值的钱,但是这样要用dfs去遍历+回溯。还有一种办法就是看看钱包中所有的钱数减去要付款的这p元后还剩下的钱。然后去凑剩下的钱,这就要凑剩下的钱需要的最少的张数了。那么最少的张数就从面值大的开始贪心就行了。如果想用了大面值得就会使得小面值得不需要的话,那说明一个问题就是大面值的总是小面值的倍数关系,这样才保证可以先使用大面值的钱。但是在面值中20,50,200,500,是没有倍数关系的,那怎么办呢?可以将20,200或者50,500的化成与其他成倍数的关系的。在这里我化的是50,500的,对于50面值的而言,可以假设50用的是奇数张还是偶数张,然后再两张两张的用(也就是当成100的用了)。若是奇数的话就先用一张,不然就直接两张两张的用。500同理。这样去判断能不能凑成总的-p元。
Too Rich
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1253 Accepted Submission(s): 299
Problem Description
You are a rich person, and you think your wallet is too heavy and full now. So you want to give me some money by buying a lovely pusheen sticker which costs pdollars
from me. To make your wallet lighter, you decide to pay exactly p dollars
by as many coins and/or banknotes as possible.
For example, if p=17 and
you have two $10 coins,
four $5 coins,
and eight $1 coins,
you will pay it by two $5 coins
and seven $1 coins.
But this task is incredibly hard since you are too rich and the sticker is too expensive and pusheen is too lovely, please write a program to calculate the best solution.
Input
The first line contains an integer T indicating
the total number of test cases. Each test case is a line with 11 integers p,c1,c5,c10,c20,c50,c100,c200,c500,c1000,c2000,
specifying the price of the pusheen sticker, and the number of coins and banknotes in each denomination. The number ci means
how many coins/banknotes in denominations of i dollars
in your wallet.
1≤T≤20000
0≤p≤109
0≤ci≤100000
Output
For each test case, please output the maximum number of coins and/or banknotes he can pay for exactly p dollars
in a line. If you cannot pay for exactly p dollars,
please simply output '-1'.
Sample Input
3
17 8 4 2 0 0 0 0 0 0 0
100 99 0 0 0 0 0 0 0 0 0
2015 9 8 7 6 5 4 3 2 1 0
Sample Output
9
-1
36
Source
2015ACM/ICPC亚洲区长春站-重现赛(感谢东北师大)
题目大意:某人在钱包中有面值为1,5,10,20,,等的硬币分别为num[i]张。然后要这个人要付款p元,问恰好能凑成这p元所需要的最多的硬币的张数,如果不能准确的凑成p元输出-1。
题解:首先想到的就是用贪心,先考虑花小面值的钱,但是这样要用dfs去遍历+回溯。还有一种办法就是看看钱包中所有的钱数减去要付款的这p元后还剩下的钱。然后去凑剩下的钱,这就要凑剩下的钱需要的最少的张数了。那么最少的张数就从面值大的开始贪心就行了。如果想用了大面值得就会使得小面值得不需要的话,那说明一个问题就是大面值的总是小面值的倍数关系,这样才保证可以先使用大面值的钱。但是在面值中20,50,200,500,是没有倍数关系的,那怎么办呢?可以将20,200或者50,500的化成与其他成倍数的关系的。在这里我化的是50,500的,对于50面值的而言,可以假设50用的是奇数张还是偶数张,然后再两张两张的用(也就是当成100的用了)。若是奇数的话就先用一张,不然就直接两张两张的用。500同理。这样去判断能不能凑成总的-p元。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; LL num[15],a[]= {1,5,10,20,50,100,200,500,1000,2000}; LL work(LL p) { LL ans=0; for(int i=9; i>=0; i--) { if(p==0)break; if(num[i]<=0)continue; if(a[i]==50||a[i]==500) { if(num[i]>=2) { LL m=num[i]/2; LL temp=min(p,a[i]*2*m);///两张两张的用 LL k=temp/(a[i]*2); p=p-k*a[i]*2; ans+=k*2; } } else { LL temp=min(p,a[i]*num[i]); LL k=temp/a[i]; p=p-k*a[i]; ans+=k; } } if(p==0)return ans; return -1; } int main() { int T; LL p,sum,ret,ans,d; scanf("%d",&T); while(T--) { sum=ret=0; scanf("%lld",&p); for(int i=0; i<10; i++) { scanf("%lld",&num[i]); sum+=num[i]*a[i]; ret+=num[i]; } if(p>sum) { printf("-1\n"); continue; } p=sum-p; ///剩下p元 ans=-1; ///50,500都用偶数张 d=work(p); if(d!=-1) { if(ans==-1)ans=d; else ans=min(ans,d); } ///50用奇数张 if(p>=50&&num[4]>0) { num[4]--; d=work(p-50); num[4]++; if(d!=-1) { if(ans==-1)ans=d+1; else ans=min(ans,d+1); } } ///500用奇数张 if(p>=500&&num[7]>0) { num[7]--; d=work(p-500); num[7]++; if(d!=-1) { if(ans==-1)ans=d+1; else ans=min(ans,d+1); } } ///50,500都用奇数张 if(p>=550&&num[4]>0&&num[7]>0) { num[4]--; num[7]--; d=work(p-550); num[4]++; num[7]++; if(d!=-1) { if(ans==-1)ans=d+2; else ans=min(ans,d+2); } } if(ans==-1)printf("-1\n"); else printf("%lld\n",ret-ans); } return 0; }
相关文章推荐
- HDU 5527(Too Rich-贪心)
- A - Too Rich HDU - 5527
- Selecting courses HDU - 3697 贪心 思维
- hdu 4898 LCP+贪心思维
- HDU 5527 Too Rich (好题 贪心 DFS)
- HDU 5527 Too Rich (2015长春站A题&&贪心)
- hdu 5821 Ball 贪心+思维
- hdu 5073 Galaxy【思维+贪心】
- hdu 4803 Poor Warehouse Keeper (贪心思维)
- hdu5969-贪心&思维&证明-最大的异或
- HDU5399——贪心——Too Simple
- HDU 6060 RXD and dividing(贪心,思维)
- hdu 6090 Rikka with Graph(思维 +贪心+轮图)
- hdu 5527 Too Rich(贪心)
- HDU 5773 The All-purpose Zero(LIS+贪心思维)
- HDU 4343 多查询求区间内的最大不相交区间个数-思维&贪心-卡时间&二分&剪枝
- hdu 4091 数学思维题贪心
- HDU - 4803 Poor Warehouse Keeper 贪心 + 思维
- hdu 5281 Senior's Gun(贪心)(思维)
- HDU 5744 Keep On Movin(思维+贪心)