zoukankan      html  css  js  c++  java
  • USACO 4.1.2 fence8

    题目:

    http://ace.delos.com/usacoprob2?a=m0gi84wTGvp&S=fence8

    http://pingce.ayyz.cn:9000/usaco/data/20110129214306/fence8.html

    Fence Rails
    Burch, Kolstad, and Schrijvers

    Farmer John is trying to erect a fence around part of his field. He has decided on the shape of the fence and has even already installed the posts, but he's having a problem with the rails. The local lumber store has dropped off boards of varying lengths; Farmer John must create as many of the rails he needs from the supplied boards.

    Of course, Farmer John can cut the boards, so a 9 foot board can be cut into a 5 foot rail and a 4 foot rail (or three 3 foot rails, etc.). Farmer John has an `ideal saw', so ignore the `kerf' (distance lost during sawing); presume that perfect cuts can be made.

    The lengths required for the rails might or might not include duplicates (e.g., a three foot rail and also another three foot rail might both be required). There is no need to manufacture more rails (or more of any kind of rail) than called for the list of required rails.

    PROGRAM NAME: fence8

    INPUT FORMAT

    Line 1: N (1 <= N <= 50), the number of boards
    Line 2..N+1: N lines, each containing a single integer that represents the length of one supplied board
    Line N+2: R (1 <= R <= 1023), the number of rails
    Line N+3..N+R+1: R lines, each containing a single integer (1 <= ri <= 128) that represents the length of a single required fence rail

    SAMPLE INPUT (file fence8.in)

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

    OUTPUT FORMAT

    A single integer on a line that is the total number of fence rails that can be cut from the supplied boards. Of course, it might not be possible to cut all the possible rails from the given boards.

    SAMPLE OUTPUT (file fence8.out)

    7

    题解:
      USACO又一道恶心题,题意就是一个多重背包问题,但是数据过大,裸搜是要爆的。在经历TLE,怎么剪也剪不动后,参考了一下别人的题解,终于明白几种好的做法了。

      1、最后制作的rail一定都是最小的。
      2、优先将大的rail向小的board里面放。
      3、对于rail[i]=rail[i+1],第i+1个rail一定是放在第i个rail之后。
      4、二分答案。
      5、如果剩下的空间已不能放完剩下的rail就可以剪掉了。

      做完这道题后,感觉自己搜索剪枝还非常弱,今后应当更加努力才是。

    View Code
     1 /*
     2 ID:zhongha1
     3 PROB:fence8
     4 LANG:C++
     5 */
     6 
     7 #include<cstdio>
     8 #include<cstdlib>
     9 #include<cstring>
    10 #include<algorithm>
    11 
    12 using namespace std;
    13 
    14 const int maxn=2000;
    15 
    16 int orz[maxn],take,r,h[maxn],l[maxn],n,sum[maxn],tv;
    17 
    18 bool cmp(int a,int b)
    19 {
    20     return a>b;
    21 }
    22 
    23 bool dfs(int now,int nowp,int maxp)
    24 {
    25     if (now==0) return true;
    26     if (take>tv-sum[maxp]) return false;
    27     for (int a=nowp;a<=n;a++)
    28         if (l[a]>=h[now])
    29         {
    30             l[a]-=h[now];
    31             if (l[a]<h[1]) take+=l[a];
    32             if (h[now]==h[now-1])
    33             {
    34                 if (dfs(now-1,a,maxp)) return true;
    35             }
    36             else
    37             {
    38                 if (dfs(now-1,1,maxp)) return true;
    39             }
    40             if (l[a]<h[1]) take-=l[a];
    41             l[a]+=h[now];
    42         }
    43     return false;
    44 }
    45 
    46 bool check(int now)
    47 {
    48     return dfs(now,1,now);
    49 }
    50 
    51 int main()
    52 {
    53     freopen("fence8.in","r",stdin);
    54     freopen("fence8.out","w",stdout);
    55 
    56     scanf("%d",&n);
    57     for (int a=1;a<=n;a++)
    58         scanf("%d",&l[a]),tv+=l[a];
    59     scanf("%d",&r);
    60     for (int a=1;a<=r;a++)
    61         scanf("%d",&h[a]);
    62     sort(l+1,l+n+1);
    63     sort(h+1,h+r+1);
    64     for (int a=1;a<=r;a++)
    65         sum[a]=sum[a-1]+h[a];
    66     for (int a=1;a<=n;a++)
    67         orz[a]=l[a];
    68     int le=0;
    69     while (sum[r]>tv)
    70         r--;
    71     if (r==0)
    72     {
    73         printf("0\n");
    74         return 0;
    75     }
    76     r++;
    77     while (le+1!=r)
    78     {
    79         for (int a=1;a<=n;a++)
    80             l[a]=orz[a];
    81         take=0;
    82         int m=(le+r)>>1;
    83         if (check(m)) le=m;
    84         else r=m;
    85     }
    86     printf("%d\n",le);
    87 
    88     return 0;
    89 }



  • 相关阅读:
    SpringBoot自定义错误页面,SpringBoot 404、500错误提示页面
    SpringBoot切换Tomcat容器,SpringBoot使用Jetty容器
    SpringBoot 国际化配置,SpringBoot Locale 国际化
    SpringBoot Logback配置,SpringBoot日志配置
    SpringBoot thymeleaf使用方法,thymeleaf模板迭代
    SpringBoot thymeleaf模板页面没提示,SpringBoot thymeleaf模板插件安装
    JSP判断闰年
    JSP求和计算
    JSP指令
    jsp新建项目
  • 原文地址:https://www.cnblogs.com/zhonghaoxi/p/2519577.html
Copyright © 2011-2022 走看看