• [SCOI2005]栅栏 二分+dfs


    这个题真的是太nb了,各种骚

    二分答案,肯定要减最小的mid个,从大往小搜每一个木板,从大往小枚举所用的木材

    当当前木材比最短的木板还短,就扔到垃圾堆里,并记录waste,当 waste+sum>tot 时,return

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #define N 2005
    using namespace std;
    int n,m,w[N],nd[N],ans,ANS,sum[N],tt;
    void dfs(int x,int y,int wst,int mid){
        if(wst+sum[mid]>tt)return;
        if(y<=0){ans=1;return;}
        for(int i=x;i<=n;i++){
            if(w[i]>=nd[y]){
                w[i]-=nd[y];
                if(w[i]<nd[1]) wst+=w[i];
                if(nd[y]==nd[y-1]) dfs(i,y-1,wst,mid);
                else dfs(1,y-1,wst,mid);
                if(w[i]<nd[1]) wst-=w[i];
                w[i]+=nd[y];
                if(ans==1)return;
            }
        }
    }
    bool da(int a,int b){return a>b;}
    int main(){
        //freopen("fence8.in","r",stdin);
        //freopen("fence8.out","w",stdout);
        scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&w[i]),tt+=w[i];
        scanf("%d",&m); for(int i=1;i<=m;i++)scanf("%d",&nd[i]);
        sort(w+1,w+n+1,da);sort(nd+1,nd+m+1);
        for(int i=1;i<=m;i++)sum[i]=sum[i-1]+nd[i];
        int l=0,r=m,mid;
        while(l<=r){
            mid=(l+r)>>1;
            ans=0;dfs(1,mid,0,mid);
            if(ans){ANS=mid;l=mid+1;}
            else r=mid-1;
        }
        printf("%d
    ",ANS);
        return 0;
    }



  • 相关阅读:
    MVC模式的学生信息增删改查
    常用排序算法
    2803 爱丽丝·玛格特罗依德
    3118 高精度练习之除法
    中秋练习题
    poj2011
    P1558 色板游戏
    P1830 轰炸III
    P1656 炸铁路
    1067 机器翻译
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746668.html
Copyright © 2020-2023  润新知