题目大意
ATM中有n种类型的纸币,但ATM中每次最多只能取出k张纸币,并且每次取出的纸币类型不能超过两种,老板现在要求你取q次钱,每次恰好取出x元,并在取出x元的基础上需要你满足取出的纸币张数最少,请问每次取钱满足的纸币张数最少为多少,如果无法取出整x元,输出-1。
输入:
第一行两个整数 n, k (1 ≤ n ≤ 5000, 1 ≤ k ≤ 20).
接下来一行 n 个整数 ai (1 ≤ ai ≤ 10^7) — 表示每种纸币的面值大小 ai
接下来一行一个整数 q (1 ≤ q ≤ 20) — 表示你需要取钱的次数.
接下来 q行每行一个整数 xi (1 ≤ xi ≤ 2·10^8) — 表示你需要在ATM中取多少钱.
输出:
对于每次取钱输出一个整数表示所取纸币张数的最小值,或者输出 - 1, 如果无法满足金额要求;
思路,先把每种纸币面值记录打表,然后进行枚举每一种取x张时,枚举1到k-x是否有满足的金额然后更新ans
AC代码:
#include<bits/stdc++.h>
#define js ios::sync_with_stdio(false)
#define ll long long
using namespace std;
const ll N=2e5+5;
const ll INF=0x3f3f3f;
ll a[N];
unordered_map<ll,int>mp;
void solve(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
mp[a[i]]=1;
}
sort(a+1,a+1+n);
int q;
cin>>q;
while(q--){
int xx,ans=k+20;
cin>>xx;
for(int i=1;i<=n&&a[i]<=xx;i++){
for(int j=1;j<=k;j++){
if(a[i]*j==xx){
ans=min(ans,j);
}
else{
for(int z=1;z<=k-j;z++){
if((xx-a[i]*j)>0&&(xx-a[i]*j)%z==0&&mp.count((xx-a[i]*j)/z)){
ans=min(ans,j+z);
break;
}
}
}
}
}
if(ans>k)cout<<"-1\n";
else cout<<ans<<endl;
}
}
signed main(){
js;
solve();
return 0;
}