zoukankan      html  css  js  c++  java
  • 暴搜 栅栏

    问题 A: [SCOI2005]栅栏
    时间限制: 1 Sec 内存限制: 162 MB
    题目描述
    农夫约翰打算建立一个栅栏将他的牧场给围起来,因此他需要一些特定规格的木材。于是农夫约翰到木材店购
    买木材。可是木材店老板说他这里只剩下少部分大规格的木板了。不过约翰可以购买这些木板,然后切割成他所需
    要的规格。而且约翰有一把神奇的锯子,用它来锯木板,不会产生任何损失,也就是说长度为10的木板可以切成长
    度为8和2的两个木板。你的任务:给你约翰所需要的木板的规格,还有木材店老板能够给出的木材的规格,求约翰
    最多能够得到多少他所需要的木板。
    输入
    第一行为整数m(m<= 50)表示木材店老板可以提供多少块木材给约翰。紧跟着m行为老板提供的每一块木板的长
    度。接下来一行(即第m+2行)为整数n(n <= 1000),表示约翰需要多少木材。接下来n行表示他所需要的每一块木板
    的长度。木材的规格小于32767。(对于店老板提供的和约翰需要的每块木板,你只能使用一次)。
    输出
    只有一行,为约翰最多能够得到的符合条件的木板的个数。

    样例输入
    4
    30
    40
    50
    25
    10
    15
    16
    17
    18
    19
    20
    21
    25
    24
    30
    样例输出
    7
    提示
    25切出 21 30切出 20 40切出 19、18 50切出 15、16、17

    主要就是考虑各种剪枝。设n块的是A,m块的是B.
    根据贪心策略,先满足较小的A板一定最优,先用较小的B板最优。
    然后,来二分可能的答案。
    再然后,如果浪费的板子长度加上当前答案要求的总长度>B板总长度,返回。
    然后如果B[i]==B[i-1],那么他满足一个什么对称性。。。我不懂,但这时,对B板的枚举可以改变范围,也就是从当前枚举的i开始。(具体看代码)
    没了。。。→_→

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int m,n,c[55],a[55],b[1025],B[1025],sum,mid,w;
    inline int dfs(int x,int pos)
    {
        if(!x)return 1;
        if(B[mid]+w>sum)return 0;
        for(int i=pos;i<=m;i++)
            if(c[i]>=b[x])
            {
                c[i]-=b[x];
                if(c[i]<b[1])w+=c[i];
                if(b[x]==b[x-1]){if(dfs(x-1,i))return 1;}
                else if(dfs(x-1,1))return 1;
                if(c[i]<b[1])w-=c[i];
                c[i]+=b[x];
            }
        return 0;
    }
    int yjn()
    {
        cin>>m;for(int i=1;i<=m;i++)scanf("%d",&a[i]),sum+=a[i];
        cin>>n;for(int i=1;i<=n;i++)scanf("%d",&b[i]);
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++)B[i]=b[i]+B[i-1];
        sort(a+1,a+m+1);
        while(b[n]>a[m])n--;
        int l=0,r=n,ans;
        while(l<=r)
        {
            mid=(l+r)/2;w=0;memcpy(c,a,sizeof(a));
            if(dfs(mid,1))ans=mid,l=mid+1;
            else r=mid-1;
        }
        cout<<ans;
    }
    int qty=yjn();
    int main(){;}
  • 相关阅读:
    python — 文件操作
    Android存储
    JAVA 里面 synchronized作用
    UML元素
    ubuntu18.04 命令行安装gradle
    UML时序图
    视觉SLAM中的数学——解方程AX=b与矩阵分解:奇异值分解(SVD分解) 特征值分解 QR分解 三角分解 LLT分解
    现行最小二乘过约束和欠约束如何求解
    SLAM-G2O分析
    自定义Gradle插件
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632674.html
Copyright © 2011-2022 走看看