题解:
暴搜+二分+剪枝
二分答案,暴力判断是否有解
然后加上剪枝
代码:
#include<bits/stdc++.h> using namespace std; const int N=2005; int rest,c[N],sum[N],s,a[N],n,m,b[N]; int dfs(int x,int y) { if (x<=0)return 1; if (rest+sum[x]>s)return 0; for (int i=y;i<=n;i++) if (c[i]>=b[x]) { c[i]-=b[x]; if (c[i]<b[1])rest+=c[i]; if (b[x]==b[x-1]){if (dfs(x-1,i))return 1;} else {if (dfs(x-1,1))return 1;} if (c[i]<b[1])rest-=c[i]; c[i]+=b[x]; } return 0; } int pd(int x) { for (int i=1;i<=n;i++)c[i]=a[i]; rest=0; return dfs(x,1); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++)scanf("%d",&a[i]),s+=a[i]; scanf("%d",&m); for (int i=1;i<=m;i++)scanf("%d",&b[i]); sort(a+1,a+n+1);sort(b+1,b+m+1); for (int i=1;i<=m;i++)sum[i]=sum[i-1]+b[i]; while (sum[m]>s)m--; int l=0,r=m; while (l<r) { int mid=(l+r)/2; if (pd(mid+1))l=mid+1; else r=mid; } printf("%d",l); }