这个题。。。只能说比较水。。。
排序后,算一个前缀和,二分dfs查找答案。。。加上两个剪枝就过了。。。QVQ
我只能刷这种水题。。。我太菜了。。。QVQ
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<algorithm> #define maxn 100010 using namespace std; int a[maxn],b[maxn],c[maxn]; int n,m,ans,tot,waste,mid; inline bool check(int x,int st) { if(waste>tot-c[mid]) return 0; if(x==0) return 1; for(int i=st;i<=m;i++) if(a[i]>=b[x]) { bool flag=0; a[i]-=b[x]; if(a[i]<b[1]) waste+=a[i]; if(b[x-1]==b[x]) flag=check(x-1,i); else flag=check(x-1,1); if(a[i]<b[1]) waste-=a[i]; a[i]+=b[x]; if(flag==1) return 1; } return 0; } int main() { scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) tot+=a[i]; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&b[i]); sort(a+1,a+1+m); sort(b+1,b+1+n); for(int i=1;i<=n;i++) c[i]=c[i-1]+b[i]; while(c[n]>tot) n--; int l=0,r=n; while(l<=r) { int mid=l+r>>1; if(check(mid,1)) ans=mid,l=mid+1; else r=mid-1; } printf("%d ",ans); }