以前听lyp讲过这道题,现在发现自己的搜索还是不太熟练,加了两遍可行性剪枝,结果又WA又T,发现加剪枝和不加完全是两个速度。具体怎么搜的还是看代码吧。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 1010
using namespace std;
int a[maxn],b[maxn];
int n,m;
int suma[maxn],sumb[maxn];
int rest[maxn];
int ans,mid;
bool cmp(int x,int y)
{
return x>y;
}
bool dfs(int i)
{
if (i==0) return 1;
int sum=0;
for (int j=1;j<=n;j++) if (rest[j]>=b[1]) sum+=rest[j];
if (sum<sumb[i]) return 0;
for (int j=1;j<=n;j++)
if (rest[j]>=b[i])
{
rest[j]-=b[i];
if (dfs(i-1)) return 1;
rest[j]+=b[i];
}
return 0;
}
bool check()
{
ans=0;
for (int i=1;i<=n;i++) rest[i]=a[i];
return dfs(mid);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&m);
for (int i=1;i<=m;i++) scanf("%d",&b[i]);
sort(a+1,a+n+1,cmp);
sort(b+1,b+m+1);
for (int i=1;i<=n;i++) suma[i]=suma[i-1]+a[i];
for (int i=1;i<=m;i++) sumb[i]=sumb[i-1]+b[i];
for (int i=1;i<=m;i++) if (sumb[i]>suma[n]) {m=i-1;break;}
int l=0,r=m,ans;
while (l<=r)
{
mid=(l+r)/2;
if (check()) l=mid+1,ans=mid; else r=mid-1;
}
printf("%d\n",ans);
return 0;
}