zoukankan      html  css  js  c++  java
  • BZOJ1082: [SCOI2005]栅栏

    【传送门:BZOJ1082


    简要题意:

      给出m块有长度的可切割木板,n块有长度的需要木板,求出最多能够切割出多少块需要木板


    题解:

      二分答案,然后用搜索来判断这个答案是否能够达到,比较简单

      但是需要剪枝,其实就是减去一些不必要的搜索,先快排两种木板,如果最小需要的木板比可切割的一些木板还要大的话,证明这些可切割木板没用,如果可切割的最大木板比一些需要的木板小,证明这些需要的木板无法符合条件


    参考代码:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    typedef long long LL;
    using namespace std;
    bool flag;
    int n,m,mid;
    int a[55],b[1005],bl[1005];
    LL sa;
    int sb[1005];
    void dfs(int ak,int bk,int w)
    {
        if(bk==0)flag=1;
        while(ak<=n&&a[ak]<b[1]){w+=a[ak];ak++;}
        if(flag||ak>n)return;
        if(w+sb[mid]>sa)return;
        int t=ak,t1=ak,t2=bk,t3=w;
        if(b[bk]==b[bk+1]&&bk!=mid) t=bl[bk+1];
        for(int i=t;i<=n;i++)
        {
            if(a[i]>=b[bk])
            {
                bl[bk]=i;a[i]-=b[bk];
                bk--;
                dfs(ak,bk,w);
                ak=t1;bk=t2;w=t3;a[i]+=b[t2];
            }
        }
    }
    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);
        sort(b+1,b+m+1);
        while(b[m]>a[n]) m--;
        int tot=0;
        for(int i=1;i<=n;i++) if(a[i]>b[1])a[++tot]=a[i];
        n=tot;
        for(int i=1;i<=n;i++) sa+=a[i];
        for(int i=1;i<=m;i++) sb[i]=sb[i-1]+b[i];
        int l=1,r=m,ans=0;
        while(l<=r)
        {
            mid=(l+r)/2;
            flag=0;
            dfs(1,mid,0);
            if(flag!=0)ans=mid,l=mid+1;
            else r=mid-1;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    +1和*2
    线段树(区间最大值和最大值的个数)
    CodeForces
    莫队算法入门(暴力而不失优雅)
    二分迷宫
    全错排公式
    C++ PAT乙 1051. 复数乘法 (15)
    C++ PAT乙 1070. 结绳(25)
    C++ PAT乙 1080. MOOC期终成绩 (25)
    C++ PAT 1073. 多选题常见计分法(20)
  • 原文地址:https://www.cnblogs.com/Never-mind/p/7606229.html
Copyright © 2011-2022 走看看