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

    题目大意:

      有一些木材,可以没有浪费地将一根木材分成几块木板(比如长度为10的木板可以切成长度为8和2的两块木板)。现在你希望得到一些长度的木板,问通过分割木材最多能得到几块想要的木板。

    思路:

      首先,长度短的木板一定比长度长的木板容易得到,因此若要得到最多的木板,它们必定是所有木板中最短的——可以对木板排序后二分答案(用k表示)。

      判断是否合法就用搜索,但数据有点大,要用到两个剪枝。一个是若有一根木材被切开后剩下的长度比最短的木板还短则将其累加入waste,当waste+前k块木板的长度和>木材的总长度时即可return(这十分显然);二是把木材也排序,木板从大到小去搜索而木板从小到大去枚举,若当前的木板长度与上一块木板相同,则从切出上一块木板的木材开始枚举(之前的木材肯定不够用),否则从第一根开始枚举。

    代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 using namespace std;
     5 int n,m,waste,ans,tot,l,r,i,mid,a[51],b[1111],sum[1111],f[51];
     6  
     7 bool dfs(int k,int x)
     8 {
     9     if (!k) return 1;
    10     if (waste+sum[mid]>tot) return 0;
    11     for (int i=x;i<=m;i++)
    12         if (f[i]>=b[k])
    13         {
    14             f[i]-=b[k];
    15             if (f[i]<b[1]) waste+=f[i];
    16             if (b[k]==b[k-1])
    17             {
    18                 if (dfs(k-1,i)) return 1;
    19             }
    20             else if (dfs(k-1,1)) return 1;
    21             if (f[i]<b[1]) waste-=f[i];
    22             f[i]+=b[k];
    23         }
    24     return 0;
    25 }
    26 
    27 int read()
    28 {
    29     int x=0;
    30     char ch=getchar();
    31     while (ch<'0' || ch>'9') ch=getchar();
    32     while (ch>='0' && ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    33     return x;
    34 }
    35  
    36 int main()
    37 {
    38     for (m=read(),i=1;i<=m;i++) tot+=a[i]=read();
    39     for (n=read(),i=1;i<=n;i++) b[i]=read();
    40     sort(a+1,a+m+1),sort(b+1,b+n+1);
    41     for (i=1;i<=n;i++) sum[i]=sum[i-1]+b[i];
    42     while (sum[m]>tot) m--;
    43     for (l=0,r=n;l<=r;)
    44     {
    45         mid=(l+r)>>1;
    46         waste=0;
    47         for (i=1;i<=m;i++) f[i]=a[i];
    48         if (dfs(mid,1)) l=mid+1,ans=mid;
    49         else r=mid-1;
    50     }
    51     printf("%d
    ",ans);
    52     return 0;
    53 }
    我一直在繁华的苍凉中徘徊着,用一颗OI的心寻找着生命和宇宙的美妙与玄奥。
  • 相关阅读:
    css实现截取文本
    ob_clean()解决php验证码图片无法显示
    JS获取url参数,修改url参数
    mysql模糊查询特殊字符(\,%和_)处理
    apache反向代理和监听多个端口设置
    页面底部自适应浏览器窗口高度
    变量相关考虑
    php非法输入数据类型
    php socket模拟http中post或get提交数据
    华为专利的 hybrid 端口
  • 原文地址:https://www.cnblogs.com/HHshy/p/5821511.html
Copyright © 2011-2022 走看看