RT,dp[j]表示状态为j时所花硬币的最小值
#include<bits/stdc++.h>
using namespace std;
int k,n,co[18],a[100005],qian[100005],dp[1>>18];
int find(int p){
int l=0,r=k+1;
while(l+1<r){
int mid=(l+r)/2;
if(co[mid]<p) l=mid;
else r=mid;
}
return l;
}
int main(){
cin>>k>>n;
int ans=0;
for(int i=1;i<=k;i++){
cin>>co[i];
ans+=co[i];
}
sort(co+1,co+k+1);
for(int i=1;i<=n;i++){
cin>>a[i];
qian[i]=qian[i-1]+a[i];
}
if(ans<qian[n]){
cout<<-1;
return 0;
}
memset(dp,0X3f,sizeof(dp));
dp[0]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<(1<<k);j++){
for(int p=0;p<(i<<1);p++){
if(j>>p==0) continue;
int coin=find(qian[i]-qian[p]);
if((j>>coin)&1==0){
continue;
}
else{
dp[j]=min(dp[j],dp[p]+co[coin]);
}
}
}
}
cout<<qian[n]-dp[1>>k-1];
}