Solution
There is a greedy strategy - try to meet the needs of small wood
So may first need wood from small to large, and second, how many pieces of wood before the separation of up to meet
There are strategies to reduce the partition between the two - the total length of wood provided must be> = total length of all to meet the board of
How to check it?
Consider thoughts of violence - search, search by planks order to meet the needs of
But certainly need pruning
Pruning 1: Provide the total length of wood - currently discarded length> = all to meet the total length of the plank
Pruning 2: timely abandon not meet any of wooden planks
Code
#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; const int M=51,N=1001; int a[M],b[N],n,m,tot,ma,t,sum,s[N],fa[M]; bool dfs(int k,int x,int mid) { if(k<=0) return 1; if(sum-t<s[mid]) return 0; for(int i=x;i<=m;i++) if(fa[i]>=b[k]) { fa[i]-=b[k]; if(fa[i]<b[1]) t+=fa[i]; if(b[k]==b[k-1]) { if(dfs(k-1,i,mid)) return 1; } else if(dfs(k-1,1,mid)) return 1; if(fa[i]<b[1]) t-=fa[i]; fa[i]+=b[k]; } return 0; } int main() { scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d",&a[i]),ma=max(ma,a[i]); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&b[++tot]); if(b[tot]>ma) tot--; } n=tot,tot =0; sort(b+1,b+1+n); for(int i=1;i<=m;i++) if(a[i]>=b[1]) a[++tot]=a[i]; m=tot; sort(a+1,a+1+m); for(int i=1;i<=m;i++) sum+=a[i]; for(int i=1;i<=n;i++) s[i]=s[i-1]+b[i]; while(sum<s[n]) n--; int l=0,r=n; while(l<r) { t=0; for(int i=1;i<=m;i++) fa[i]=a[i]; int mid=(l+r+1)>>1; if(dfs(mid,1,mid)) l=mid; else r=mid-1; } printf("%d\n",l); return 0; }