Too Rich(貪心+DFS)
阿新 • • 發佈:2018-10-02
sum frame mina coin arch sca map rst show dollars 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.
dollars in your wallet.
1≤T≤20000
0≤p≤109
0≤ci≤100000
Too Rich
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): 2032 Accepted Submission(s): 529
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
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亞洲區長春站-重現賽(感謝東北師大) 這題求的是用最多的硬幣湊成P元,我們可以反著想,用最少的硬幣湊成剩下的錢,這樣就轉換成一道經典的貪心問題 但是要註意的是,大的硬幣不一定是小的硬幣的整數倍,所以需要用DFS搜索出最優解,具體看代碼
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <cmath> 5 #include <iostream> 6 #include <algorithm> 7 #include <queue> 8 #include <stack> 9 #include <vector> 10 #include <set> 11 #include <map> 12 #define maxn 50010 13 #define lson l,mid,rt<<1 14 #define rson mid+1,r,rt<<1|1 15 const long long INF=0x3f3f3f3f3f3f3f3f; 16 using namespace std; 17 long long coin[] = {0,1, 5, 10, 20, 50, 100, 200, 500, 1000, 2000}; 18 long long a[12]; 19 long long ans; 20 21 void dfs(int pos,long long sum,long long num){ 22 if(sum==0){ 23 ans=min(ans,num); 24 return; 25 } 26 if(pos<1){ 27 return; 28 } 29 long long tmp=min(a[pos],sum/coin[pos]); 30 dfs(pos-1,sum-tmp*coin[pos],num+tmp); 31 if(tmp>0){//去掉一個硬幣的情況 32 tmp--; 33 dfs(pos-1,sum-tmp*coin[pos],num+tmp); 34 } 35 } 36 37 int main(){ 38 int t; 39 scanf("%d",&t); 40 while(t--){ 41 int total=0; 42 long long sum=0; 43 for(int i=0;i<11;i++){ 44 scanf("%lld",&a[i]); 45 sum+=coin[i]*a[i]; 46 total+=a[i]; 47 } 48 total-=a[0];//a[0]表示p 49 if(sum<a[0]){ 50 puts("-1"); 51 continue; 52 } 53 sum-=a[0]; 54 ans=INF; 55 dfs(10,sum,0); 56 if(ans==INF){ 57 puts("-1"); 58 } 59 else{ 60 printf("%lld\n",total-ans); 61 } 62 } 63 }View Code
Too Rich(貪心+DFS)