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