zoukankan      html  css  js  c++  java
  • CH2401 送礼物 双向搜索

    双向搜索:把前一半的可行状态搜出来,然后sort+unique,之后搜后一半时,结束时二分一下前一半的答案,拼出一个与W尽量接近的ans来更新

    ps:距LYD说前一半取n/2+2时跑的最快。。。不知,,,

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define R register int
    #define uint unsigned int
    using namespace std;
    inline int g() {
        R ret=0; register char ch; while(!isdigit(ch=getchar()));
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret;
    } 
    int n,m,hf,w[50];
    uint W,ans,a[(1<<23)+1];
    inline void dfs(int i,uint sum) {
        if(i==hf) {a[++m]=sum; return ;}
        dfs(i+1,sum); if(sum+w[i]<=W) dfs(i+1,sum+w[i]);
    }
    inline void dfs2(int i,uint sum) {
        if(i==n+1) {
            R tmp=upper_bound(a+1,a+m+1,W-sum)-a-1; //cout<<W-sum<<" "<<tmp<<" "<<a[tmp]<<endl;
            ans=max(ans,sum+a[tmp]); return;
        } dfs2(i+1,sum); if(sum+w[i]<=W) dfs2(i+1,sum+w[i]);
    }
    signed main() {
        W=g(),n=g();
        for(R i=1;i<=n;++i) w[i]=g();
        sort(w+1,w+n+1,greater<int>());
        hf=(n>>1)+3; dfs(1,0); sort(a+1,a+m+1); 
        m=unique(a+1,a+m+1)-a-1;
        //for(R i=1;i<=40;++i) cout<<a[i]<<" "; cout<<endl;
        dfs2(hf,0); printf("%d
    ",ans);
    }

    2019.04.26

  • 相关阅读:
    会场安排
    Comet OJ
    CodeForces1154F
    CodeForces1154E
    2019.08.25校内模拟赛Graph
    2019.08.25校内模拟赛Page
    [MtOI2019]灵梦的计算器
    [MtOI2019]永夜的报应
    [NOI2018]归程
    USACO[CowCoupons]
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10772515.html
Copyright © 2011-2022 走看看