• [BZOJ1082][SCOI2005]栅栏 二分+搜索减枝


    1082: [SCOI2005]栅栏

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2430  Solved: 1034
    [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

    HINT

    25切出 21 30切出 20 40切出 19、18 50切出 15、16、17

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 int m,n;
     9 int re[101];
    10 int a[101],b[1001];
    11 int sum,ned;
    12 int waste=0;
    13 bool dfs(int now,int st) {
    14     if(now==0) return 1;
    15     if(waste+ned>sum) return 0;
    16     for(int i=st;i<=m;i++) {
    17         if(a[i]>=b[now])
    18         {
    19             a[i]-=b[now];
    20             if(a[i]<b[1]) waste+=a[i];
    21             if(b[now]==b[now-1]) {if(dfs(now-1,i)) return 1;}
    22             else if(dfs(now-1,1)) return 1;
    23             if(a[i]<b[1]) waste-=a[i];
    24             a[i]+=b[now];
    25         }
    26     }
    27     return 0;
    28 }
    29 bool check(int mid) {
    30     ned=0;waste=0;
    31     for(int i=1;i<=mid;i++) ned+=b[i];
    32     for(int i=1;i<=m;i++) a[i]=re[i];
    33     return dfs(mid,1);
    34 }
    35 int main() {
    36     scanf("%d",&m);
    37     for(int i=1;i<=m;i++){scanf("%d",&re[i]);sum+=re[i];}
    38     scanf("%d",&n);
    39     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    40     sort(a+1,a+m+1);
    41     sort(b+1,b+n+1);
    42     int l=0,r=n;
    43     while(l<=r) {
    44         int mid=(l+r)>>1;
    45         if(check(mid)) l=mid+1;
    46         else r=mid-1;
    47     }
    48     printf("%d",l-1);
    49 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    常见HTTP状态(304,200等)
    ymPrompt消息提示组件 2.0,4.0
    将类型生成为模块
    about ValueType
    利用接口来改变已装箱值类型中的字段
    virtual\interface\abstract Class
    Response.Write("alert('hi')");显示在页面上
    The type eclipse.core.runtime.Plugin cannot be resolved.的解决
    Ubuntu11.04地址栏调整为文字模式
    Java的局部内部类以及final类型的参数和变量
  • 原文地址:https://www.cnblogs.com/wls001/p/7705166.html
Copyright © 2020-2023  润新知