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.
 

 

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.

1T20000
0p109
0ci100000
 

 

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 }
View Code

 

转载于:https://www.cnblogs.com/StupidBoy/p/4937185.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值