CSU 1510Happy Robot(dp)

Input

There will be at most 1000 test cases. Each case contains a command sequence with no more than 1000 characters.

Output

For each test case, print the case number, followed by minimal/maximal possible x (in this order), then the minimal/maximal possible y.

Sample Input
F?F
L??
LFFFRF
Sample Output
Case 1: 1 3 -1 1
Case 2: -1 1 0 2
Case 3: 1 1 3 3

Hint

想法:

这题坑的地方就在于不能够往平面上去想,最开始是dp[x][y][d]表示在坐标(x,y)位置,方向为d,得到的坐标极值。

但肯定超时。。。

所以只能够聪明一点,对字符串做dp了。。

dp[i][j]表示到达第i个字符的命令,此时机器人的方向为j时得到的坐标极值,状态表示出来了,方程就很简单了。。

由于要求Xmin,Xmax,Ymin,Ymax,所以四次DP即可。。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define max(a,b) (a) > (b) ? (a) : (b)
#define min(a,b) (a) < (b) ? (a) : (b)
using namespace std;
const int maxn = 1005;
const int inf = 0x3f3f3f3f;
int dp[maxn][4],n;
char str[maxn];


int MAX(int a,int b,int c,int d)
{
    return max(a,max(b,max(c,d)));
}


int MIN(int a,int b,int c,int d)
{
    return min(a,min(b,min(c,d)));
}


void DP1()
{
    for(int i = 0; i < n; i++)
        for(int j = 0; j < 4; j++)
            dp[i][j] = inf;
    if(str[0] == 'F')
        dp[0][1] = 1;
    else if(str[0] == 'L')
        dp[0][0] = 0;
    else if(str[0] == 'R')
        dp[0][2] = 0;
    else
    {
        dp[0][0] = 0;
        dp[0][1] = 1;
        dp[0][2] = 0;
    }
    for(int i = 1; i < n; i++)
        for(int j = 0; j < 4; j++) //上一个指令执行后的方向
        {
            if(str[i] == 'F') //前进
            {
                if(j == 0) //向上
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
                else if(j == 1) //向右
                    dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
                else if(j == 2) //向下
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
                else //向左
                    dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
            }
            else if(str[i] == 'L')
            {
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
            }
            else if(str[i] == 'R')
            {
                int d = (j + 1) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
            }
            else
            {
                if(j == 0) //向上
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
                else if(j == 1) //向右
                    dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
                else if(j == 2) //向下
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
                else //向左
                    dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
                d = (j + 1) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
            }
        }
}


void DP2()
{
    for(int i = 0; i < n; i++)
        for(int j = 0; j < 4; j++)
            dp[i][j] = -inf;
    if(str[0] == 'F')
        dp[0][1] = 1;
    else if(str[0] == 'L')
        dp[0][0] = 0;
    else if(str[0] == 'R')
        dp[0][2] = 0;
    else
    {
        dp[0][0] = 0;
        dp[0][1] = 1;
        dp[0][2] = 0;
    }
    for(int i = 1; i < n; i++)
        for(int j = 0; j < 4; j++) //上一个指令执行后的方向
        {
            if(str[i] == 'F') //前进
            {
                if(j == 0) //向上
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
                else if(j == 1) //向右
                    dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
                else if(j == 2) //向下
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
                else //向左
                    dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
            }
            else if(str[i] == 'L')
            {
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
            }
            else if(str[i] == 'R')
            {
                int d = (j + 1) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
            }
            else
            {
                if(j == 0) //向上
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
                else if(j == 1) //向右
                    dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
                else if(j == 2) //向下
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
                else //向左
                    dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
                d = (j + 1) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
            }
        }
}


void DP3()
{
    for(int i = 0; i < n; i++)
        for(int j = 0; j < 4; j++)
            dp[i][j] = inf;
    if(str[0] == 'F')
        dp[0][1] = 0;
    else if(str[0] == 'L')
        dp[0][0] = 0;
    else if(str[0] == 'R')
        dp[0][2] = 0;
    else
    {
        dp[0][0] = 0;
        dp[0][1] = 0;
        dp[0][2] = 0;
    }
    for(int i = 1; i < n; i++)
        for(int j = 0; j < 4; j++) //上一个指令执行后的方向
        {
            if(str[i] == 'F') //前进
            {
                if(j == 0) //向上
                    dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
                else if(j == 1) //向右
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
                else if(j == 2) //向下
                    dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
                else //向左
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
            }
            else if(str[i] == 'L')
            {
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
            }
            else if(str[i] == 'R')
            {
                int d = (j + 1) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
            }
            else
            {
                if(j == 0) //向上
                    dp[i][j] = min(dp[i][j],dp[i-1][j] + 1);
                else if(j == 1) //向右
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
                else if(j == 2) //向下
                    dp[i][j] = min(dp[i][j],dp[i-1][j] - 1);
                else //向左
                    dp[i][j] = min(dp[i][j],dp[i-1][j]);
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
                d = (j + 1) % 4;
                dp[i][d] = min(dp[i][d],dp[i-1][j]);
            }
        }
}


void DP4()
{
    for(int i = 0; i < n; i++)
        for(int j = 0; j < 4; j++)
            dp[i][j] = -inf;
    if(str[0] == 'F')
        dp[0][1] = 0;
    else if(str[0] == 'L')
        dp[0][0] = 0;
    else if(str[0] == 'R')
        dp[0][2] = 0;
    else
    {
        dp[0][0] = 0;
        dp[0][1] = 0;
        dp[0][2] = 0;
    }
    for(int i = 1; i < n; i++)
        for(int j = 0; j < 4; j++) //上一个指令执行后的方向
        {
            if(str[i] == 'F') //前进
            {
                if(j == 0) //向上
                    dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
                else if(j == 1) //向右
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
                else if(j == 2) //向下
                    dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
                else //向左
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
            }
            else if(str[i] == 'L')
            {
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
            }
            else if(str[i] == 'R')
            {
                int d = (j + 1) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
            }
            else
            {
                if(j == 0) //向上
                    dp[i][j] = max(dp[i][j],dp[i-1][j] + 1);
                else if(j == 1) //向右
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
                else if(j == 2) //向下
                    dp[i][j] = max(dp[i][j],dp[i-1][j] - 1);
                else //向左
                    dp[i][j] = max(dp[i][j],dp[i-1][j]);
                int d = ((j - 1) % 4 + 4) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
                d = (j + 1) % 4;
                dp[i][d] = max(dp[i][d],dp[i-1][j]);
            }
        }
}


int main()
{
    int cas = 1;
    while(scanf("%s",str)!=EOF)
    {
        n = strlen(str);
        DP1();
        printf("Case %d: %d ",cas++,MIN(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
        DP2();
        printf("%d ",MAX(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
        DP3();
        printf("%d ",MIN(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
        DP4();
        printf("%d\n",MAX(dp[n-1][0],dp[n-1][1],dp[n-1][2],dp[n-1][3]));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值