题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6685
题意:Rikka有4种硬币,分别是10分20分50分100分,餐厅里有n道菜,每道菜都有各自的价格wi,Rikka会购买其中的一道菜,问她最少需要带几个硬币出门,使她对于任何一道菜都能恰好付完钱并且没有找零。
T(1≤T≤500) n(1≤n≤100) (1≤wi≤109)
思路:容易得出,10分的硬币最多带1个,20分的硬币最多带3个,50分的硬币最多带1个,于是我们可以枚举每种硬币带几个,剩下的整百部分就用100分的硬币填充,取总和最小的情况即可。
下面是非常优美的AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int T,n;
int a[100005];
int main()
{
scanf("%d",&T);
while(T--)
{
int ans=0x7f7f7f7f;
scanf("%d",&n);
int w=0;
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
if(a[i]%10!=0)
w=-1;
}
if(w==-1)
{
printf("-1\n");
continue;
}
int flag=0;
int mm=0;
for(int i=0; i<=1; i++)
for(int j=0; j<=3; j++)
for(int k=0; k<=1; k++)
{
for(int l=0; l<n; l++)
{
for(int ii=i; ii>=0; ii--)
for(int jj=j; jj>=0; jj--)
for(int kk=k; kk>=0; kk--)
{
if((ii*50+jj*20+kk*10)%100==a[l]%100)
{
flag++;
mm=max(mm,a[l]-(ii*50+jj*20+kk*10));
goto endd;
}
}
endd:
;
}
if(flag==n)
{
if(mm/100+i+j+k<=ans)
{
ans=i+j+k+mm/100;
}
}
flag=0;mm=0;
}
printf("%d\n",ans);
}
}
/***
5
500 440 370 250 110
9
**/
非常暴力的思路。
需要注意的地方:ii,jj,kk要从大到小遍历,使得a[l]减去的值最大,反之会wa。