2015ACM/ICPC亚洲区长春站 A hdu 5527 Too Rich
Too Rich
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 245 Accepted Submission(s): 76
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.
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
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
题意:博客吃回车,没办法。
就是说用尽量多的钞票组合成币值p,问最多用多少。
分析:
尽量用比值小的,如果先从小的开始,我们不知道小的币值能不能凑出当前所需钱数
所以从大的开始
可以发现,如果后面的钱数一共能凑出a,现在共需b,那么当前这个币值我们所需要凑出的就是(b-a),所需数量显然是max(ceil((b-a)/(当前的币值), 0)
然而,这并不是绝对的,固然,这个数量可以使后面的尽量多,但是诸如20,20,20,50这样的例子,假设b是50,那么因为a是60,导致错误,所以有可能会多用一张当前的钞票
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <iostream> 9 #include <algorithm> 10 #include <map> 11 #include <set> 12 #include <ctime> 13 using namespace std; 14 typedef long long LL; 15 typedef double DB; 16 #define For(i, s, t) for(int i = (s); i <= (t); i++) 17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--) 18 #define Rep(i, t) for(int i = (0); i < (t); i++) 19 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--) 20 #define rep(i, x, t) for(int i = (x); i < (t); i++) 21 #define MIT (2147483647) 22 #define INF (1000000001) 23 #define MLL (1000000000000000001LL) 24 #define sz(x) ((int) (x).size()) 25 #define clr(x, y) memset(x, y, sizeof(x)) 26 #define puf push_front 27 #define pub push_back 28 #define pof pop_front 29 #define pob pop_back 30 #define ft first 31 #define sd second 32 #define mk make_pair 33 inline void SetIO(string Name) 34 { 35 string Input = Name+".in", 36 Output = Name+".out"; 37 freopen(Input.c_str(), "r", stdin), 38 freopen(Output.c_str(), "w", stdout); 39 } 40 41 inline int Getint() 42 { 43 int Ret = 0; 44 char Ch = ' '; 45 bool Flag = 0; 46 while(!(Ch >= '0' && Ch <= '9')) 47 { 48 if(Ch == '-') Flag ^= 1; 49 Ch = getchar(); 50 } 51 while(Ch >= '0' && Ch <= '9') 52 { 53 Ret = Ret * 10 + Ch - '0'; 54 Ch = getchar(); 55 } 56 return Flag ? -Ret : Ret; 57 } 58 59 const int N = 15, Money[] = {0, 1, 5, 10, 20, 50, 100, 200, 500, 1000, 2000}; 60 int p, Arr[N]; 61 LL Sum[N]; 62 int Ans; 63 64 inline void Solve(); 65 66 inline void Input() 67 { 68 int TestNumber = Getint(); 69 while(TestNumber--) 70 { 71 p = Getint(); 72 For(i, 1, 10) Arr[i] = Getint(); 73 Solve(); 74 } 75 } 76 77 inline void Search(int Last, int x, int Cnt) 78 { 79 if(Last < 0) return; 80 if(x < 1) 81 { 82 if(!Last) Ans = max(Ans, Cnt); 83 return; 84 } 85 LL Rest = max(Last - Sum[x - 1], 0LL); 86 int Number = Rest / Money[x]; 87 if(Rest % Money[x]) Number++; 88 if(Number <= Arr[x]) 89 Search(Last - 1LL * Number * Money[x], x - 1, Cnt + Number); 90 if(++Number <= Arr[x]) 91 Search(Last - 1LL * Number * Money[x], x - 1, Cnt + Number); 92 } 93 94 inline void Solve() 95 { 96 Sum[0] = 0; 97 For(i, 1, N) Sum[i] = Sum[i - 1] + 1LL * Arr[i] * Money[i]; 98 Ans = -1; 99 Search(p, 10, 0); 100 printf("%d\n", Ans); 101 } 102 103 int main() 104 { 105 #ifndef ONLINE_JUDGE 106 SetIO("1001"); 107 #endif 108 Input(); 109 //Solve(); 110 return 0; 111 }