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
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
Source
这题求的是用最多的硬币凑成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)
原文:https://www.cnblogs.com/Fighting-sh/p/9737269.html