zoukankan      html  css  js  c++  java
  • BZOJ1082 二分搜索

    1082: [SCOI2005]栅栏

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2247  Solved: 952
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    4
    30
    40
    50
    25
    10
    15
    16
    17
    18
    19
    20
    21
    25
    24
    30

    Sample Output

    7
     
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int a[55],b[1111],sb[1111],sa;
    int bl[1111];
    int mid,n,m;
    bool flag;
    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(w+sb[mid]>sa||ak>n) return;
        if(flag) return;
        int t=ak;
        if(b[bk]==b[bk+1]&&bk!=mid) t=bl[bk+1];
        for(int i=t; i<=n; ++i)
        {
            if(a[i]>=b[bk])
            {
                a[i]-=b[bk];
                bl[bk]=i;
                dfs(ak,bk-1,w);
                a[i]+=b[bk];
            }
        }
    }
    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<=m; ++i) sb[i]=sb[i-1]+b[i];
        for(int i=1; i<=n; ++i) sa+=a[i];
        int l=1,r=m,ans=0;
        while(l<=r)
        {
            mid=(l+r)>>1;
            flag=0;
            dfs(1,mid,0);
            if(flag) ans=mid,l=mid+1;
            else r=mid-1;
        }
        printf("%d ",ans);
    }
     
  • 相关阅读:
    压缩感知的由来
    VS2010自动崩溃问题
    随机过程好书推荐
    Kernel PCA
    稀疏性与L1范数
    豆瓣关于计算机视觉的书评及介绍
    压缩感知测量矩阵的研究现状(转)
    信号的功率谱、能量谱、频谱的区别(转)
    vc++ & matlab 换行符号
    arg min 的含义
  • 原文地址:https://www.cnblogs.com/mfys/p/7133536.html
Copyright © 2011-2022 走看看