ACM Changchun 2015 A. Too Rich
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 p dollars from me. To make your wallet lighter, you decide to pay exactly pp dollars by as many coins and/or banknotes as possible.
For example, if p = 1 and you have two 10 coins, four 5 coins, and eight 1 coins, you will pay it by two 5coins 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 Format
The first line contains an integer Tindicating the total number of test cases.
Each test case is a line with 1 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 ii dollars in your wallet.
1≤T≤20000
0≤p≤109
0≤ci?≤100000
Output Format
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‘.
樣例輸入
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
樣例輸出
9 -1 36
題目來源
ACM Changchun 2015
/* 某些面值的錢分別有若幹個,用這些錢來恰好組成某一金額的錢,問最多需要的錢的數目 逆向思維 用總價減去需求=X 那麽貪心來用最少的數目湊成X即可(也可能湊不出來) */ #include <iostream> #include <cstdio> #include <algorithm> #include <cstdlib> #include <cstring> #include <string> #include <deque> using namespace std; #define ll long long #define N 1009 const ll inf =9e18; #define gep(i,a,b) for(int i=a;i<=b;i++) #define gepp(i,a,b) for(int i=a;i>=b;i--) #define gep1(i,a,b) for(ll i=a;i<=b;i++) #define gepp1(i,a,b) for(ll i=a;i>=b;i--) #define mem(a,b) memset(a,b,sizeof(a)) ll val[]={0,1,5,10,20,50,100,200,500,1000,2000}; ll num[15],a[15]; ll ans,p; ll sum,ret; int t; void dfs(int x,ll sum,ll cnt) { if(!sum) { ans=min(ans,cnt); return ; } if(x<1) return ; a[x]=min(sum/val[x],num[x]); dfs(x-1,sum-val[x]*a[x],cnt+a[x]); if(a[x]>=1) { a[x]--; dfs(x-1,sum-val[x]*a[x],cnt+a[x]); } /* 如 : 1 150 0 0 0 3 1 1 0 0 0 0 如果沒有上面的三行就是無解 -1 但是 dfs(4,60,0) 因為 用了50,後面的就無法湊成10 但是後面的20*3可以湊成60,因此a[x]可一每次都減1,再去dfs 這樣才能考慮到所有的情況! */ } int main() { scanf("%d",&t); while(t--) { scanf("%lld",&p); mem(a,0); sum=0; ret=0; gep(i,1,10) { scanf("%lld",&num[i]); ret+=num[i]; sum+=val[i]*num[i]; } sum-=p; if(sum<0) { printf("-1\n"); continue; } ans=inf; dfs(10,sum,0); if(ans!=inf) { printf("%lld\n",ret-ans); } else{ printf("-1\n"); } } return 0; }
ACM Changchun 2015 A. Too Rich