【hdu 5527】 [2015ACM/ICPC亚洲区长春站] Too Rich 贪心

Too Rich
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 673 Accepted Submission(s): 173

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 p dollars 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 10coins,four 5 coins, and eight 1coins,youwillpayitbytwo 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

9
-1
36

Source
2015ACM/ICPC亚洲区长春站
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=5527

题意
选出凑成N的最多的钱数;

思路
从大面值到小面值贪心,剩下的只要可以被取到便取最少的大面值的;因为500,200等非倍数的存在,
反例:150,用50,20取,故取时500,50,等可能多取一个即可;

代码

#include<iostream>
#include<stdio.h>
using namespace std;
int v[11]={0,1,5,10,20,50,100,200,500,1000,2000};
int s[11];
int ans;int N;
long long T[11];
void dfs(int p,int n,int d)
{

    if(p<0) return ;
    if(d==0)
    {
        if(!p)
        ans=max(ans,n);
        return ;
    }
    long long tmp=max((long long)0,p-T[d-1]);
    int k=tmp/v[d]+(tmp%v[d]?1:0);

    if(k>s[d]) return ;
    dfs(p-k*v[d],k+n,d-1);

    k++;
    if(k<=s[d])
    dfs(p-k*v[d],k+n,d-1);
}

int main()
{
    int c;
    scanf("%d",&c);
    while(c--)
    {
        scanf("%d",&N);
        for(int i=1;i<=10;i++)
        scanf("%d",&s[i]);
        T[0]=0;
        for(int i=1;i<=10;i++)
        {
            T[i]=T[i-1]+(long long)s[i]*(long long)v[i];
        }
        ans=0;
        dfs(N,0,10);

        if(!ans) printf("-1\n");
        else printf("%d\n",ans);
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值