hdu 5527 (贪心)

一个比较好的贪心题 : http://acm.hdu.edu.cn/showproblem.php?pid=5527

思路: 对于这个题比较难的点就是在 50  和 500 的处理上,因为如果没有50 和 500 的钱币 ,那么其他的钱币就是相互对立的。我就可以直接贪心的来找了。在这里处理的时候,我可以把 两张50的看成 1张100 的,500 同理。那么我考虑反方向也就是求 所有钱的价值- 我要凑的价值, 我要凑这个数的最小钱币数, 那么我在这里枚举 50  和 500 的奇偶情况,这样就可以贪心了。

代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int inf =0x3f3f3f3f;

int val[15]={0,1,5,10,20,50,100,200,500,1000,2000};
int cnt[15];
int tmpc[15];
int Ans;
int aim;

int solve(int sum)
{
    int ans=0;
    for(int i=10;i>=1;i--){
        if(i==5|i==8){
            int c=min(sum/(val[i]*2),tmpc[i]/2);
            ans+=c*2;
            sum-=val[i]*2*c;
        }
        else{
            int c=min(tmpc[i],sum/val[i]);
            ans+=c;
            sum-=c*val[i];
        }
        if(sum<=0) break;
    }
    if(sum==0) return ans;
    else return inf;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&aim);
        int sum=0;
        int tot=0;
        for(int i=1;i<=10;i++){
            scanf("%d",&cnt[i]);
            tot+=cnt[i];
            sum+=cnt[i]*val[i];
        }
        if(sum<aim){
            printf("-1\n");
            continue;
        }
        Ans=inf;

        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=1;k<=10;k++) tmpc[k]=cnt[k];
                int tt=sum-aim;
                if(tmpc[5]&&i==1){
                    tmpc[5]--;
                    tt-=val[5];
                }
                if(tmpc[8]&&j==1){
                    tmpc[8]--;
                    tt-=val[8];
                }
                //cout<<"**** tt "<<tt<<endl;
                if(tt>=0) Ans=min(Ans,i+j+solve(tt));
            }
        }

        if(Ans==inf) printf("-1\n");
        else printf("%d\n",tot-Ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/82258222