• 1082栅栏 大视野评测


    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

    Source

    http://www.lydsy.com/JudgeOnline/problem.php?id=1082

    以上是题目描述。。。额。。其实我也没看懂。。

    一小时后。。。

    这道题的基本思路是  二分+搜索(贪心)

    注意!!注意!!先排序!!

    左端点初始为0,右端点为n;  进行二分。

    我们设可以得到mid个 进行验证;

    搜索有两个参数(k,deep),k 表示还有几个木块要get(k<n),deep表示现在进行到第几块(deep<m)

    然后就是愉快的搜索了!!!

    for (int i=deep;i<=m;i++){
        if (a[i]>=b[k]){
            a[i]-=b[k];
            if (a[i]<b[1]) sheng+=a[i];
            if (b[k-1]==b[k]) f=dfs(k-1,i);
            else f=dfs(k-1,1);
            if (a[i]<b[1]) sheng-=a[i];
            a[i]+=b[k];
            if (f) return true;
        }
    }

    优化:这里sheng表示没用的木材,如果没用的木材+需要的木材>总共的木材,return false;

    if (k==0) return true;

    不多说,参考一段代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 int a[50001]={0},b[50001]={0},s[50001]={0}; 
     6 int n,m;
     7 void qsorta(int left,int right){
     8     int i=left,j=right,mid=a[(left+right)/2];
     9     while (i<=j){
    10         while (a[i]<mid) i++;
    11         while (a[j]>mid) j--;
    12         if (i<=j) {
    13             int t=a[i]; a[i]=a[j]; a[j]=t;
    14             i++; j--;
    15         }
    16     }
    17     if (i<right) qsorta(i,right);
    18     if (left<j) qsorta(left,j);
    19 }
    20 void qsortb(int left,int right){
    21     int i=left,j=right,mid=b[(left+right)/2];
    22     while (i<=j){
    23         while (b[i]<mid) i++;
    24         while (b[j]>mid) j--;
    25         if (i<=j) {
    26             int t=b[i]; b[i]=b[j]; b[j]=t;
    27             i++; j--;
    28         }
    29     } 
    30     if (i<right) qsortb(i,right);
    31     if (left<j) qsortb(left,j);
    32 }
    33 int sheng=0,mid=0,sum=0; //sheng表示没用的木材,sum表示总共木材长度
    34 bool dfs(int k,int deep){
    35     if (k==0) return true;
    36     if (sheng+s[mid]>sum) return false;
    37     bool f;
    38     for (int i=deep;i<=m;i++){
    39         if (a[i]>=b[k]){ //如果当前这一块木材可以截出需要的木材,截下
    40             a[i]-=b[k];
    41             if (a[i]<b[1]) sheng+=a[i]; //如果这块剩余的木材长度比最小的木材长度小,就扔掉
    42             if (b[k-1]==b[k]) f=dfs(k-1,i); //如果需要的木材和前一块相等,继续做
    43             else f=dfs(k-1,1);//否则从1开始做
    44             if (a[i]<b[1]) sheng-=a[i];//回溯
    45             a[i]+=b[k]; 
    46             if (f) return true;
    47         }
    48     }
    49     return false;
    50 }
    51 int main(){ 
    52     scanf("%d",&m); for (int i=1;i<=m;i++){ scanf("%d",&a[i]); sum+=a[i]; }
    53     scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&b[i]); }
    54     qsorta(1,m); qsortb(1,n);
    55     for (int i=1;i<=n;i++) s[i]=s[i-1]+b[i]; //s[i]表示前i项的和
    56     while (s[n]>sum) n--;
    57     int l=0,r=n,ans=0;
    58     while (l<=r){
    59         mid=(l+r)/2;
    60         if (dfs(mid,1)) {
    61             l=mid+1;
    62             ans=mid; 
    63         }
    64         else r=mid-1;
    65     }
    66     printf("%d",ans);
    67     return 0;
    68 } 

    代码有点丑,别介意。

  • 相关阅读:
    C#数组学习
    关于servlet中要写初始化逻辑应该重载有参还是无参的init
    servlet初识servletConfig
    servlet通过响应头Content-Disposition实现文件下载效果
    response中setCharacterEncoding和setContentType的区别
    通过refresh响应头,定时刷新或隔n秒跳转页面
    通过location响应头实现重定向
    三层交换原理
    什么是CLOS架构?
    Cat8 八类网线是什么?与Cat5、Cat6、Cat7网线的区别?
  • 原文地址:https://www.cnblogs.com/lztlztlzt/p/6196223.html
Copyright © 2020-2023  润新知