题目链接:https://vjudge.net/contest/279984#problem/D
题目大意:就是有个物品价值p,然后我们有面值为1,5,10,50,100的纸币,问最少和最多用多少纸币正好能买这个物品。
思路:最少的话就是从最大的开始看嘛,挺简单的。最多的话就转换一下求法。假设拥有的纸币的总面值为q,那么问题就可以转换成求买价值为q-p的物品,最少要用多少纸币,就很简单了。
还有一点呢就是,我们拥有的纸币不能凑到p的时候,输出-1 -1
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <math.h>
#include <vector>
int m[110];
const int a[5]={1,5,10,50,100};
using namespace std;
typedef long long ll;
int main()
{
int T;
int A,B;
scanf("%d",&T);
while(T--)
{
int p;
scanf("%d%d%d%d%d%d",&p,&m[1],&m[5],&m[10],&m[50],&m[100]);
int sum1=p;
A=0,B=0;
int mod=p%5;
if(m[1]<mod) {
printf("-1 -1\n");
continue;
}//因为1是最小的面值,剩下的面值都是5的倍数,所以mod如果大于1纸币的个数,肯定就不能凑成p了
for(int i=4;i>=0&&sum1>0;i--)//求最小纸币
{
int temp=sum1/a[i];
if(temp<=m[a[i]])
{
A+=temp;
sum1%=a[i];
}
else {
A += m[a[i]];
sum1-= m[a[i]] * a[i];
}
}
if(sum1>0)
{
printf("-1 -1\n");
continue;
}
else//求最多的纸币。(也就是买价值为(总共的纸币面值q-p)的东西,要用的最少的纸币)
{
int q=0;
int summ=0;
for(int i=0;i<5;i++)
{
q+=m[a[i]]*a[i];//拥有的总共的纸币面值
summ+=m[a[i]];//纸币的数量
}
int sum2=q-p;//价值为(总共的纸币面值q-p)的东西
for(int i=4;i>=0&&sum2>0;i--)
{
int temp=sum2/a[i];
if(temp<=m[a[i]])
{
B+=temp;
sum2%=a[i];
}
else {
B += m[a[i]];
sum2-= m[a[i]] * a[i];
}
}
B=summ-B;
if(sum2>0)
{
printf("-1 -1\n");
continue;
}
}
printf("%d %d\n",A,B);
}
return 0;
}