HDU - 5527 A - Too Rich (贪心&&dfs)

版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/83514075

 链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5527

题意:

给出硬币面值和数量,让你用数量最多的硬币凑出给定的数.

思路:

正反思考都行.

正面想就是要尽可能多的用面值少的硬币,所以从面值大的开始考虑,假设把比它面值小的都选上后,看看需要补多少个当前面值硬币.

反面就是想去掉尽量少的硬币,使得剩下的刚好满足要求.

正:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int val[11] = {0, 1, 5, 10, 20, 50, 100, 200, 500, 1000, 2000};
ll sum[11];//前缀和
int c[11];
int ans;
void dfs(int rest, int index,int cnt)//rest 剩下的钱 index 当前处理的面值下标 cnt 数量
{
    if(rest < 0 ) return ;
    if(index == 0)
    {
        if(rest == 0)
            ans = max(ans,cnt);
        return ;
    }
    ll cur = max(rest - sum[index - 1],(ll)0);  //减去价格小的硬币价钱之和后可以由当前硬币提供的价钱
    int curnum = cur / val[index]; //可以由当前硬币提供的数量
    if(cur % val[index])//如果不能整出,那么必然要加一
    {
        curnum++;
    }
    if(curnum <= c[index])
        dfs(rest - curnum * val[index], index - 1, cnt + curnum);
    curnum++;
    if(curnum <= c[index])
        dfs(rest - curnum * val[index], index - 1, cnt + curnum);
}
int main()
{
    int t,p;
    cin>>t;
    while(t--)
    {
        memset(sum,0,sizeof sum);
        ans = -1;
        cin>>p;
        for(int  i = 1; i <= 10; i++)
            cin>>c[i];
        for(int i = 1; i <= 10 ; i++)
        {
            sum[i] = sum[i-1] + val[i] * c[i];
        }
        dfs(p,10,0);
        cout<<ans<<endl;
    }
    return 0;
}

反:

# include <iostream>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long LL;
const LL INF = 0x3f3f3f3f3f3f3f3f;
LL a[]= {0,1,5,10,20,50,100,200,500,1000,2000}, b[13];
LL ans;
void dfs(int cur, LL tot, LL cnt)
{
    if(tot < 0) return;
    if(cur == 0)
    {
        if(tot == 0)
            ans = min(ans, cnt);
        return;
    }
    LL tmp = min((LL)b[cur], tot/a[cur]);
    dfs(cur-1, tot-tmp*a[cur], cnt+tmp);
    if(tmp) dfs(cur-1, tot-(tmp-1)*a[cur], cnt+tmp-1);

}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        LL tot = 0, sum = 0, all = 0;
        ans = INF;
        scanf("%lld",&sum);
        for(int i=1; i<=10; ++i) scanf("%lld",&b[i]), tot += a[i]*b[i], all += b[i];
        if(tot < sum)
        {
            puts("-1");
            continue;
        }
        dfs(10, tot-sum, 0);
        if(ans == INF) puts("-1");
        else
            printf("%lld\n",all-ans);
    }
    return 0;
}
扫描二维码关注公众号,回复: 4066806 查看本文章

猜你喜欢

转载自blog.csdn.net/Healer66/article/details/83514075
今日推荐