acm常用技巧四 超大背包问题

来源:互联网 发布:领流量软件 编辑:程序博客网 时间:2024/05/22 04:38

一.超大背包问题

pair<LL,LL> ps[1<<(MXN/2)];void Fun(){    int n2=n/2;    for(int i=0;i<1<<n2;++i){        LL sw=0,sv=0;        for(int j=0;j<n2;++j)            if(i>>j&1){                sw+=w[j];                sv+=v[j];            }        ps[i]=make_pair(sw,sv);    }    sort(ps,ps+(1<<n2));    int m=1;    for(int i=1;i<1<<n2;++i)        if(ps[m-1].second<ps[i].second)            ps[m++]=ps[i];    LL res=0;    for(int i=0;i<1<<(n-n2);++i){        LL sw=0,sv=0;        for(int j=0;j<n-n2;++j){            if(i>>j&1){                sw+=w[n2+j];                sv+=v[n2+j];            }        }        if(sw<=W){            LL tv=(lower_bound(ps,ps+m,make_pair(W-sw,INF))-1)->second;            res=max(res,sv+tv);        }    }    printf("%lld\n",res);}

二.坐标离散化

int compress(int x1[],int x2[],int w){    vector<int> xs;    for(int i=0;i<N;++i)        for(int d=-1;d<=1;++d){            int tx1=x1[i]+d,tx2=x2[i]+d;            if(1<=tx1&&tx1<=W) xs.push_back(tx1);            if(1<=tx2&&tx2<=W) xs.push_back(tx2);        }    sort(xs.begin(),xs.end());    xs.erase(unique(xs.begin(),xs.end()),xs.end());    for(int i=0;i<N;++i){        x1[i]=find(xs.begin(),xs.end(),x1[i])-xs.begin();        x2[i]=find(xs.begin(),xs.end(),x2[i])-xs.begin();    }    return xs.size();}void Fun(){    W=compress(X1,X2,W);    H=compress(Y1,Y2,H);    memset(fld,0,sizeof(fld));    for(int i=0;i<N;++i)        for(int y=Y1[i];y<=Y2[i];++y)            for(int x=X1[i];x<=X2[i];++x)                fld[y][x]=1;    int ans=0;    for(int y=0;y<H;++y)        for(int x=0;x<W;++x){            if(fld[y][x]) continue;            ans++;            queue<pair<int,int> > que;            que.push(make_pair(x,y));            while(!que.empty()){                int sx=que.front().first,sy=que.front().second;                que.pop();                for(int i=0;i<4;++i){                    int tx=sx+dx[i],ty=sy+dy[i];                    if(tx<0||W<=tx||ty<0||H<=ty) continue;                    if(fld[ty][tx]) continue;                    que.push(make_pair(tx,ty));                    fld[ty][tx]=true;                }            }        }    printf("%d\n",ans);}