标签:hdu 3348 coins 贪心
3 33 6 6 6 6 6 10 10 10 10 10 10 11 0 1 20 20 20
6 9 1 10 -1 -1
题意:给你P a1 a5 a10 a50 a100 ,ai代表i角的硬币有ai个,问凑成P最少,最多的硬币个数。
题解:
最少直接从大到小取,最大就是不断的把面值大的转换成小的。渣渣只会暴力。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 1010
#define ll long long
using namespace std;
int s;
int a[7];///面值为c[i]的硬币剩余的个数为a[i]个
int b[7];///面值为c[i]的硬币用了b[i]个
int c[7]= {0,1,5,10,50,100};///面值
int main() {
//freopen("in.txt","r",stdin);
int t;
cin>>t;
while(t--) {
scanf("%d",&s);
for(int i=1; i<=5; i++) {
scanf("%d",&a[i]);
}
int x=s;
int Min=0,Max=0;
memset(b,0,sizeof b);
for(int i=5; i>=1; i--) {
if(x>=c[i]) {
int num=x/c[i];
if(num>=a[i])
num=a[i];
Min+=num;
a[i]-=num;
b[i]=num;
x-=num*c[i];
}
}
if(x!=0)Min=-1;
if(Min==-1) {
printf("-1 -1\n");
continue;
}
Max=Min;
///求最大值就是大的尽量转换成小的
while(1) {
int flag=1; ///标记是否有转换
for(int i=5; i>1; i--) {
if(b[i]) {///用的个数
for(int j=i-1; j>=1; j--) {
if(b[i]==0)
break;
//转换
if(a[j]*c[j]>=c[i]) {
int x=a[j]*c[j]/c[i];
if(x>=b[i]) {
Max=Max-b[i]+c[i]*b[i]/c[j];
b[j]+=c[i]*b[i]/c[j];
a[i]+=b[i];
a[j]=a[j]-c[i]*b[i]/c[j];
b[i]=0;
flag=0;
} else {
Max=Max-x+c[i]*x/c[j];
b[j]+=c[i]*x/c[j];
a[i]+=x;
a[j]=a[j]-c[i]*x/c[j];
b[i]-=x;
flag=0;
}
}
}
}
}
if(flag)
break;
}
printf("%d %d\n",Min,Max);
}
return 0;
}
标签:hdu 3348 coins 贪心
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/45135981