1. 程式人生 > >背包搜索--LH

背包搜索--LH

for int ++ algo return style cout scanf div

技術分享

題解:搜索 meet in the middle

先搜一半,假設某個狀態的體積是p,那麽就要從另一半裏找到體積小於

等於v-p 價值最大的狀態。二分+前綴和。

代碼:不會前綴和,暴力瞎寫的。沒有評測的地方..=^=

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;

int an,bn,n,m,p,q,w[50],c[50];
LL ans;
struct WP{
    LL w,c;
    
bool operator < (const WP &a) const{ return w<a.w; } }wp[1050000]; LL maxx(LL a,LL b){ return a>=b?a:b; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d%d",&w[i],&c[i]); an=n/2;bn=n-an; for(int st=0;st<(1<<an);st++){ p
++; for(int i=0;i<an;i++){ if((st>>i)&1){ wp[p].w+=w[i+1]; wp[p].c+=c[i+1]; } } } sort(wp+1,wp+p+1); for(int st=0;st<(1<<bn);st++){ WP all;all.w=0;all.c=0;//清為0 for(int i=0;i<bn;i++){
if((st>>i)&1){ all.w+=w[n-i]; all.c+=c[n-i]; } } WP gg;gg.w=m-all.w;gg.c=0; int cc=upper_bound(wp+1,wp+p+1,gg)-wp; // cout<<all.w<<" " <<gg.w<<" "<<cc<<endl; for(int i=1;i<cc;i++) ans=maxx(ans,all.c+wp[i].c); } printf("%lld\n",ans); return 0; }

背包搜索--LH