• [机房测试] 出租车


    Description

    出租车有k个停靠点,这k个停靠点依次排成一条直线,从左到右编号为1到k。出租车一次最多带4个人。共有n个人正在等待乘车,每个人都想从某个停靠点,去往另一个停靠点,即每个人的出发点和目的点不尽相同。这n个人到达各自上车的停靠点的时间均不相同,我们按到达时间的前后依次给这n个人编号为1到n,即先到的编号小。出租车公司有一个规定,先到的人必须比后到的人先上车,当然下车顺序则任意。

    出租车每次可以移动到相邻编号的停靠点,需要耗费一个单位的时间,每个人上车或者下车都需要耗费一个单位时间,出租车一开始为空,且位于1号停靠点,出租车最后停靠点任意,那么将则n个人送到目的地至少需要多少时间呢?(注:题目保证出租车到达时需要上车的人已到达出发点)

    (nleq 2000,kleq 10)

    Solution

    不考虑车上的人的具体编号,只记录他们的终点,然后再记录当前位置,和已经上过车的人数。转移考虑枚举上车或者下客。注意到当车满载时,必有一个人要下车,我们略去这个中间状态,直接从没满载转移到另一种没满载的状态,就可以省掉一维。复杂度 (O(nk^4))

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int M=11;
    const int N=2e3+7;
    
    int dp[N][M][M][M][M],n,K,u[N],v[N];
    
    inline void Min(int &x,int y){x=min(x,y);}
    inline int abs(int x){return x<0? -x:x;}
    
    int dfs(int i,int now,int x,int y,int z){
        if(i>n&&((!x)&&(!y)&&(!z))) return 0;
        int &ret=dp[i][now][x][y][z];
        if(~ret) return ret; else ret=1<<30;
        // 下车,当且仅当非空
        if(x) Min(ret,dfs(i,x,0,y,z)+abs(now-x));
        if(y) Min(ret,dfs(i,y,x,0,z)+abs(now-y));
        if(z) Min(ret,dfs(i,z,x,y,0)+abs(now-z));
        // 载人,当且仅当有人可载 
        if(i>n) return ret;
        if(x&&y&&z){
            Min(ret,dfs(i+1,v[i],x,y,z)+abs(now-u[i])+abs(u[i]-v[i]));
            Min(ret,dfs(i+1,x,v[i],y,z)+abs(now-u[i])+abs(u[i]-x));
            Min(ret,dfs(i+1,y,x,v[i],z)+abs(now-u[i])+abs(u[i]-y));
            Min(ret,dfs(i+1,z,x,y,v[i])+abs(now-u[i])+abs(u[i]-z));
        }else{
            if(!x) Min(ret,dfs(i+1,u[i],v[i],y,z)+abs(now-u[i]));
            if(!y) Min(ret,dfs(i+1,u[i],x,v[i],z)+abs(now-u[i]));
            if(!z) Min(ret,dfs(i+1,u[i],x,y,v[i])+abs(now-u[i]));
        }
        return ret;
    }
    
    int main(){
        freopen("taxi.in","r",stdin);
        freopen("taxi.out","w",stdout);
        memset(dp,-1,sizeof(dp));
        scanf("%d%d",&n,&K);
        for(int i=1;i<=n;i++) 
            scanf("%d%d",&u[i],&v[i]);
        printf("%d",dfs(1,1,0,0,0)+2*n);
    }
    
  • 相关阅读:
    英特尔“硬盘内存一体化”首款产品正式发布,读写速度超千倍,存储密度扩充十倍
    程序员,你为什么值这么多钱?
    不懂程序看的明白《黑客帝国》吗?
    程序员的工作、学习与绩效
    架构设计师能力模型
    .net平台的MongoDB使用
    转载-30分钟搞定后台登录界面(103个后台PSD源文件、素材网站)
    XAF-DevExpress.ExpressApp.DC.Xpo.XpoTypeInfoSource 生成实体的过程-学习笔记
    谈谈敏捷开发
    XAF-由于try catch导致的性能问题一例
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15501029.html
Copyright © 2020-2023  润新知