需要求的是取p钱,使总的取得硬币数最大
反向思考就是求取sum-p的钱,使总的取的硬币数最少 这样贪心起来就容易了 从最大的开始 我们可以观察 除了20 50和200 500之外其余的相邻的2个之间都是倍数关系 所以特殊除了这2个就可以了 又因为20是50+50的倍数 所以在取50的时候要考虑少取一个50的情况(200 500同) 比如有3个50的时候 50+50是20的倍数可以表示 但如果是50*3的话无法用20表示 需要都跑一下
#include#define inf 0x3f3f3f3f#define mem(a,b) memset(a,b,sizeof(a))#define rep(i,a,b) for(int i=a;i<=b;i++)#define int long longusing namespace std;int a[15]={0,1,5,10,20,50,100,200,500,1000,2000};int mub[15],ans;void dfs(int sum,int t,int now){ if(sum==0) { ans=min(t,ans); return ; } if(now==0) return ; int m=sum/a[now]; m=min(m,mub[now]); dfs(sum-m*a[now],t+m,now-1); if(m) { m--; dfs(sum-m*a[now],t+m,now-1); }}#undef intint main(){#define int long long int t; cin>>t; while(t--) { ans=inf; int n,sum=0,all=0; cin>>n; rep(i,1,10) cin>>mub[i],sum+=a[i]*mub[i],all+=mub[i]; sum=sum-n; if(sum>0) dfs(sum,0,10); cout<<(ans==inf?-1:all-ans)<