Codeforces Round #483 (Div. 2) E. Elevator

E. Elevator
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You work in a big office. It is a 9 floor building with an elevator that can accommodate up to 4 people. It is your responsibility to manage this elevator.

Today you are late, so there are queues on some floors already. For each person you know the floor where he currently is and the floor he wants to reach. Also, you know the order in which people came to the elevator.

According to the company's rules, if an employee comes to the elevator earlier than another one, he has to enter the elevator earlier too (even if these employees stay on different floors). Note that the employees are allowed to leave the elevator in arbitrary order.

The elevator has two commands:

  • Go up or down one floor. The movement takes 1 second.
  • Open the doors on the current floor. During this operation all the employees who have reached their destination get out of the elevator. Then all the employees on the floor get in the elevator in the order they are queued up while it doesn't contradict the company's rules and there is enough space in the elevator. Each employee spends 1 second to get inside and outside the elevator.

Initially the elevator is empty and is located on the floor 1.

You are interested what is the minimum possible time you need to spend to deliver all the employees to their destination. It is not necessary to return the elevator to the floor 1.

Input

The first line contains an integer n (1 ≤ n ≤ 2000) — the number of employees.

The i-th of the next n lines contains two integers ai and bi (1 ≤ ai, bi ≤ 9ai ≠ bi) — the floor on which an employee initially is, and the floor he wants to reach.

The employees are given in the order they came to the elevator.

Output

Print a single integer — the minimal possible time in seconds.

Examples
input
Copy
2
3 5
5 3
output
Copy
10
input
Copy
2
5 3
3 5
output
Copy
12

题目大意:

身为一个电梯管理人员,我们的任务是管理电梯,今天你迟到了,电梯门口排起了长队,你需要将他们快速送到想要的楼层。

有些规定:电梯只能容纳四个人。先来的人必须先进电梯,不管他们在第几层。电梯移动一层需要1S,进一个人1S,出一个人1S。

电梯最后不用回到第一层,按 到达电梯门口的人 的顺序给出 所在楼层 和 目标楼层。求他们所有人到目标楼层的时间。

题目思路:

对于某个时刻中,电梯的状态有这么几种:

1.电梯没人:那么肯定是去接人

2.电梯没满人:那可以选择去接人,或者送一个人到目的地

3.电梯满人:那么肯定是送一个人到目的地

4.电梯没满人,但是不用接人了:那么肯定也是选择送一个人到目的地

对于以上这么几个状态,可以用dfs(k,level,a,b,c) 来表示,因为电梯只能容纳四个人,k表示第K个人一定在电梯中,前k-1个不是在目的地,就是在电梯里,所以当满人的时候,就一定要先送一个人下去,所以这时候只需要记录三个人的目的地,a,b,c 。

level表示电梯当前在第几层。

代码:

#include<bits/stdc++.h>

using namespace std;

int n;
int people[2010],want[2010];
int dp[2010][12][12][12][12];

int dis(int a,int b){return abs(a - b);}

int dfs(int k,int level,int a,int b,int c)
{
    if(~dp[k][level][a][b][c] )
        return dp[k][level][a][b][c];

    int ret = 1000000;

    if(k > n) ///如果超过了总人数,选择一个送到目的地
    {
        if(a == 0 && b == 0 && c == 0)
            return 0;
        if(a)   ret = min(ret, dfs(k,a,0,b,c) + dis(level,a) + 1);
        if(b)   ret = min(ret, dfs(k,b,a,0,c) + dis(level,b) + 1);
        if(c)   ret = min(ret, dfs(k,c,a,b,0) + dis(level,c) + 1);

        return dp[k][level][a][b][c] = ret;
    }

    ///有人就选择一个到目的地
    if(a) ret = min(ret, dfs(k,a,0,b,c) + dis(level,a) + 1);
    if(b) ret = min(ret, dfs(k,b,a,0,c) + dis(level,b) + 1);
    if(c) ret = min(ret, dfs(k,c,a,b,0) + dis(level,c) + 1);

    if(a && b && c)///满人的话就选择一个到目的地
    {
        ret = min(ret, dfs(k + 1,want[k],a,b,c) + dis(level,people[k]) + dis(people[k],want[k]) + 2);
        ret = min(ret, dfs(k + 1,a,want[k],b,c) + dis(level,people[k]) + dis(people[k],a) + 2);
        ret = min(ret, dfs(k + 1,b,a,want[k],c) + dis(level,people[k]) + dis(people[k],b) + 2);
        ret = min(ret, dfs(k + 1,c,a,b,want[k]) + dis(level,people[k]) + dis(people[k],c) + 2);
    }
    else ///没满人的话还可以选择在上一个人
    {
             if(!a) ret = min(ret ,dfs(k + 1,people[k],want[k],b,c) +  dis(level,people[k]) + 1);
        else if(!b) ret = min(ret ,dfs(k + 1,people[k],a,want[k],c) +  dis(level,people[k]) + 1);
        else        ret = min(ret ,dfs(k + 1,people[k],a,b,want[k]) +  dis(level,people[k]) + 1);
    }

    return dp[k][level][a][b][c] = ret;
}

int main()
{
    scanf("%d",&n);

    memset(dp,0xff,sizeof(dp));

    for(int i = 1;i <= n;i ++)
        scanf("%d %d",&people[i],&want[i]);

    printf("%d\n",dfs(1,1,0,0,0));


    return 0;
}


猜你喜欢

转载自blog.csdn.net/ii0789789789/article/details/80609817