【Usaco】Fence8

来源:互联网 发布:php 开源 多用户商城 编辑:程序博客网 时间:2024/06/06 00:45

Description

农夫约翰打算建立一个栅栏将他的牧场给围起来,因此他需要一些特定规格的木材。于是农夫约翰到木材店购买木材。可是木材店老板说他这里只剩下少部分大规格的木板了。不过约翰可以购买这些木板,然后切割成他所需要的规格。而且约翰有一把神奇的锯子,用它来锯木板,不会产生任何损失,也就是说长度为10的木板可以切成长度为8和2 的两个木板。
你的任务:给你约翰所需要的木板的规格,还有木材店老板能够给出的木材的规格,求约翰最多能够得到多少他所需要的木板。

Input

第一行为整数m(m≤50)表示木材店老板可以提供多少块木材给约翰。紧跟着m行为 老板提供的每一块木板的长度。接下来一行(即第m+2行)为整数n(n≤1000),表示约翰需要多少木材。接下来n行表示他所需要的每一块木板的长度。 木材的规格小于32767。(对于店老板提供的和约翰需要的每块木板,你只能使用一次)。

Output

只有一行,为约翰最多能够得到的符合条件的木板的个数。

Sample Input

4304050251015161718192021252430

Sample Output

7

HINT

25切出21

30切出20

40切出19、18

50切出 15、16、17

Source


 迭代加深搜索+剪枝

迭代加深搜索思想。

枚举答案K,考虑到能否切出K个木头,那么我们当然选最小的K个来切。

1、对于原材料,我们是首选最大的还是最小的?显然,首选大的能够更容易切出,也更容易得到答案。

2、对于目标木头,我们是优先得到最大的还是最小的?显然,由于K个木头我们都要得到,那么当然先把最大的(最难得到的)先得到,这种搜索策略更优。

3、假设总原材料为all,前K个木头总和为sum,那么all-sum就是这一次切割过程中能【浪费】的最大数目。对于一个切剩下的原材料,若它比最小的目标木头还要小,则它可视为【无用】的,无用的也就是浪费的,若浪费>all-sum,则直接返回false

4、对于一个目标木头B,若它的长度和上一个木头A的长度相同,那么我们切B所用的原材料(B')一定是从切A所用的原材料(A')位置开始找。(这其实就是一个剪掉重复计算的剪枝)

5、迭代可以使用二分,但其实枚举也慢不了多少。


#include<stdio.h>#include<algorithm>using namespace std;int a[55],b[1010],c[1010];int max1(int a,int b){return a>b?a:b;}bool cmp(int a,int b){return a>b;}int n,m;bool dfs(int l,int r,int sum,int p){    if(r==0)return 1;    if(sum>p)return 0;    for(int i=l;i<=m;i++)    {        if(a[i]>=b[r])        {            a[i]-=b[r];            int q=(a[i]<b[1]?a[i]:0);            l=(b[r]==b[r-1]?i:1);            if(dfs(l,r-1,sum+q,p)){a[i]+=b[r];return 1;}            a[i]+=b[r];        }    }    return 0;}int main(){    int maxx,all;    maxx=0;    all=0;    scanf("%d",&m);    for(int i=1;i<=m;i++){scanf("%d",&a[i]);all+=a[i];maxx=max1(maxx,a[i]);}    scanf("%d",&n);    for(int i=1;i<=n;i++){scanf("%d",&b[i]);if(b[i]>maxx){i--;n--;}}    int ans;    sort(a+1,a+m+1,cmp);    sort(b+1,b+n+1);    c[1]=b[1];    for(int i=2;i<=n;i++)c[i]=c[i-1]+b[i];    for(ans=1;ans<=n&&dfs(1,ans,0,all-c[ans]);ans++);    printf("%d",ans-1);    return 0;} /**************************************************************    Problem: 1269    User: xrq    Language: C++    Result: Accepted    Time:4 ms    Memory:968 kb****************************************************************/


0 0