您的位置:首页 > 其它

HDU 3348 coins 贪心 最少/最多硬币问题

2017-03-16 19:26 344 查看
    题意是说现在给你一定数目的1角,5角,1元,5元和10元硬币,要买一个P角的东西(注意单位是毛......一开始没仔细看直接当成元算的),问最少和最多分别用多少硬币能买到,如果凑不出正好的钱,则输出“-1 -1”。

    最少多少硬币比较好处理一些,直接用贪心的算法,从面值最大的硬币开始向下一个个遍历就可以了,因为为了花费最少则一定要把能花的最大面值硬币花了。如果遍历后发现没办法凑齐,则输出“-1 -1”。然后比较麻烦的是处理最多用多少硬币,这里采用交换的方式,之前最少的方式已经找出来了,再进行替换就可以了。表示当时队内比赛这一步总是处理不好,比赛结束后参考下网上的博客才发现在替换的时候我只替换了一遍就结束了,并没有得到最佳的结果。然后很神奇的比赛时间延长了......

    下面AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int b[10]={1,5,10,50,100};
int a[15],c[15];

int main()
{
int T;
int n;
int t,k;
int i,j,g;
int num;
int maxn,minn;
scanf("%d",&T);
while(T--)
{
minn=0;
maxn=0;
g=1;
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
scanf("%d%d%d%d%d%d",&n,&a[0],&a[1],&a[2],&a[3],&a[4]);
t=n;
for(i=4;i>=0;i--)
{
if(t==0)
break;
if(t>=b[i])
{
num=t/b[i];
if(num>=a[i])
num=a[i];
c[i]=num;
minn+=num;
a[i]-=num;
t=t-num*b[i];
}
}
if(t!=0)
{
cout<<-1<<" "<<-1<<endl;
continue;
}
cout<<minn<<" ";
maxn=minn;
while(g)
{
g=0;
for(i=4;i>0;i--)
{
if(c[i]==0)
continue;
for(j=i-1;j>=0;j--)
{
if(c[i]==0)
break;
k=a[j]*b[j];
if(k>=b[i])
{
t=k/b[i];
if(t>=c[i])
{
maxn=maxn-c[i]+b[i]*c[i]/b[j];
c[j]+=b[i]*c[i]/b[j];
a[i]+=c[i];
a[j]=a[j]-b[i]*c[i]/b[j];
c[i]=0;
g=1;
}
else
{
maxn=maxn-t+b[i]*t/b[j];
c[j]+=b[i]*t/b[j];
a[i]+=t;
a[j]=a[j]-b[i]*t/b[j];
c[i]-=t;
g=1;

4000
}
}
}
}
}
cout<<maxn<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: