1. 程式人生 > >ACM Changchun 2015 A. Too Rich

ACM Changchun 2015 A. Too Rich

think lov nom continue maximum write i++ ups htm

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.

1T20000

0p109

0ci?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