Too Rich UVALive - 7183(贪心)
需要求的是取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<bits/stdc++.h>
#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 long
using 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 int
int 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)<<endl;
}
return 0;
}