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\n",ans); }
2019.04.26