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);
    }
     
  • 相关阅读:
    高性能网站优化——兼容
    高性能网站优化——开发
    leetcode刷题日记: 19.删除链表的倒数第k个节点
    大数据处理技术学习
    <java复习>返回可变对象引用的get方法要点
    <C++网络编程随笔>常用Socket函数总结
    <leetcode每日一题>数组中的第K个最大元素
    <leetcode每日一题>二叉树的LCA查找
    codeforce round615 div3 B
    暑假作业竟然如此芳香(hdu4145枚举+贪心)
  • 原文地址:https://www.cnblogs.com/mfys/p/7133536.html
Copyright © 2011-2022 走看看