hdu5527贪心

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yqdjl6/article/details/83718083

2015年的长春ACM现场赛的一道金牌题,今天做了做重现赛,刚上来就看A,感觉是道xjb贪心的题,看到好多签到题就去做了,最后反应过来的时候居然没人做这题,终榜的时候也只有很少的人做出来,以为是自己想简单了,结果发现就是一道贪心题,不过很有意思。首先我们要使得硬币数量最多,那就使剩下的硬币数最少,剩下的硬币数最少直接贪心就可以,但问题是我们以前贪心的时候5是1的倍数,10是5的倍数,20是10的倍数,在这种情况下每一个大额的硬币都能由若干小的硬币去替换,但问题是题目中有20-50和200-500这种硬币,就不能简单的贪心,比如说有20 20 20 50,我想要60,从大到小贪就贪不了,看到别人的博客发现大家都有一个回退的操作,就是我贪心的时候有限按最大的贪,然后把最大的-1再贪一次,这样就保证的了比如说一个50发现不行以后把50删了,进行次大值的贪心,但证明没怎么看懂

#include<bits/stdc++.h>
using namespace std;
using LL = int64_t;
const LL INF=1e18;
struct Node {
    LL x,num;
}node[20];
LL ans;

void dfs(LL cnt,LL sum,LL num) {
    if(sum<0) return ;
    if(cnt==0) {
        if(sum==0) ans=min(ans,num);
        return ;
    }
    LL temp=min(sum/node[cnt].x,node[cnt].num);
    dfs(cnt-1,sum-temp*node[cnt].x,num+temp);
    if(temp) dfs(cnt-1,sum-(temp-1)*node[cnt].x,num+temp-1);
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    node[1].x=1,node[2].x=5,node[3].x=10,node[4].x=20,node[5].x=50,node[6].x=100,node[7].x=200,node[8].x=500,node[9].x=1000,node[10].x=2000;
    int T;cin>>T;
    while (T--){
        LL p,sum=0,num=0;ans=INF;cin>>p;
        for(int i=1;i<=10;i++) cin>>node[i].num,sum+=node[i].x*node[i].num,num+=node[i].num;
        if(sum<p) cout<<"-1\n";
        else {
            dfs(10,sum-p,0);
            if(ans!=INF) cout<<num-ans<<"\n";
            else cout<<"-1\n";
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yqdjl6/article/details/83718083