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.

1T20000

0p109

0ci100000

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;
}

 

转载于:https://www.cnblogs.com/tingtin/p/9562702.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值