bzoj 2516: 电梯

Description

Input

Output

状压dp,状态表示为表示当前在第x层,电梯内有哪些人,哪些人还没到终点

#include<cstdio>
#include<cstring>
#include<algorithm>
int T,n,k,ts[16],as[16],bs[16],xs[32];
int h[1055][1055],f[60007][25],tr[60007][2];
int abs(int x){return x>0?x:-x;}
void mins(int&a,int b){a>b?a=b:0;}
int max(int a,int b){return a>b?a:b;}
int main(){
    for(scanf("%d",&T);T;--T){
        scanf("%d%d",&n,&k);
        int xp=0;
        for(int i=0;i<n;++i){
            scanf("%d%d%d",ts+i,as+i,bs+i);
            xs[xp++]=as[i];
            xs[xp++]=bs[i];
        }
        int mx=1<<n,idp=0;
        for(int i=0;i<mx;++i)for(int j=0;j<mx;++j)if((i|j)==i){
            tr[idp][0]=i;tr[idp][1]=j;
            h[i][j]=idp++;
        }
        memset(f,0x3f,sizeof(f[0])*(idp+2));
        std::sort(xs,xs+xp);
        xp=std::unique(xs,xs+xp)-xs;
        for(int i=0;i<n;++i){
            as[i]=std::lower_bound(xs,xs+xp,as[i])-xs;
            bs[i]=std::lower_bound(xs,xs+xp,bs[i])-xs;
        }
        for(int i=0;i<xp;++i)f[0][i]=abs(xs[i]-k);
        for(int i=0;i<idp-1;++i){
            int A=tr[i][0],B=tr[i][1],*F0=f[i];
            for(int k=0;k<n;++k)if(A>>k&1){
                if(B>>k&1)continue;
                int&F=f[h[A][B|1<<k]][bs[k]],_x=xs[bs[k]];
                for(int j=0;j<xp;++j)mins(F,F0[j]+abs(xs[j]-_x));
            }else{
                int&F=f[h[A|1<<k][B]][as[k]],_x=xs[as[k]];
                for(int j=0;j<xp;++j)mins(F,max(ts[k],F0[j]+abs(xs[j]-_x)));
            }
        }
        int ans=0x3f3f3f3f;
        for(int i=0;i<xp;++i)mins(ans,f[idp-1][i]);
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ccz181078/p/7009457.html