A
来源:互联网 发布:医院数据分析 编辑:程序博客网 时间:2024/06/05 20:48
题目大致意思是你现在有一堆硬币,有10种不同币值的钱a[i]个,先要凑出p元,要使得使用的钱币最多。
首先我们可以将问题转化一下,将尽可能多的硬币凑出p转化为尽可能少的硬币凑出sum_val-p。
其实我们只要特判下50,500这两种货币的奇偶性就可以大胆的贪心去了哈哈。
为什么要特判50,500的奇偶性呢,因为50,不能由20组成,会出问题500同理
#include <bits/stdc++.h>using namespace std;typedef long long LL;const int INF = 0x3f3f3f3f;const int maxn = 110;int num[maxn];int copy_num[maxn];int val[10] = {1,5,10,20,50,100,200,500,1000,2000};int T,p,sum_val,sum_num,lave;int Step;inline int solve(int Num,int step){ if(Num == 0) return Step; if(Num > 0 && step < 0) return -1; if(step == 4 || step == 7){ int Te = min(Num/(2*val[step]),copy_num[step]/2); Step += Te*2; Num -= Te*2*val[step]; } else{ int Te = min(Num/val[step],copy_num[step]); Step += Te; Num -= Te*val[step]; } solve(Num,step-1);}int main(){ scanf("%d",&T); while(T--){ scanf("%d",&p); sum_num = 0; sum_val = 0; for(int i = 0; i < 10; i++){ scanf("%d",&num[i]); sum_num += num[i]; sum_val += num[i]*val[i]; } lave = sum_val - p; if(lave < 0) puts("-1"); else if(lave == 0) printf("%d\n",sum_num); else{ int ans = INF; for(int i = 0; i < 2; i++){ for(int j = 0; j < 2; j++){ memcpy(copy_num,num,sizeof(num)); lave = sum_val - p; if(i){ lave -= 50; copy_num[4]--; if(lave < 0 || copy_num[4] < 0) continue; } if(j){ lave -= 500; copy_num[7]--; if(lave < 0 || copy_num[7] < 0) continue; } Step = 0; int lala = solve(lave,9); if(lala != -1) ans = min(ans,Step+i+j); } } if(ans == INF) puts("-1"); else printf("%d\n",sum_num-ans); } } return 0;}