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;
}
最少多少硬币比较好处理一些,直接用贪心的算法,从面值最大的硬币开始向下一个个遍历就可以了,因为为了花费最少则一定要把能花的最大面值硬币花了。如果遍历后发现没办法凑齐,则输出“-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;
}
相关文章推荐
- hdu 3348 coins(贪心)
- 贪心算法解决最少圆覆盖最多点问题
- HDU 3348 coins 最小化纸币数量贪心,和最大化纸币数量贪心
- HDU 2037 今年暑假不AC (贪心---求最多不相交区间问题)
- 最少硬币问题-贪心选择
- coins(hdu 3348 贪心 + 多重背包)
- 贪心 逆向思维 HDU 3348 coins
- HDU 3348 coins 贪心
- HDU 3348 coins【贪心】
- 最少硬币问题
- 找最少硬币问题
- 最少硬币问题
- 最少硬币找零问题
- hdu 2844 Coins 多重背包问题
- 最少硬币问题(无穷硬币)
- HDU 1800 简单贪心 13.1.10用trie重做 ---其实是统计出现次数最多的单词
- 最少零钱问题 最少硬币问题
- 最少硬币问题--贪心算法
- 最少硬币问题
- hdu 1257 最少拦截系统(DP + 贪心)