您的位置:首页 > 移动开发

csu 1510 Happy Robot(字符串DP,记忆化搜索)

2016-08-16 10:31 253 查看
Happy RobotTime Limit: 1 Sec  Memory Limit:
128 MB
Submit: 182  Solved: 85

[Submit][Status][Web
Board]

Description



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


题意:给一个字符串,包含有四种字符,F表示向前走,L表示在当前位置向左转,R表示在当前位置向右转,?表示执行上面三种任意一种都可以

机器人从(0,0)开始,输出x,y的最小值和最大值

思路:用记忆化搜索从后往前搜索,搜过的位置可以直接返回。DP里要保存在当前这个位置朝向某个方向极值

队友还提供了一种字符串DP的思路,其实也差不多。

关键在于此题不能在二维平面考虑,要在字符串上考虑才可以。

这里给出两个代码,记忆化搜索的方向是上下左右,字符串DP的方向是上右下左

代码1:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define N 1050
#define INF 99999999
struct Node
{
int minx,maxx,miny,maxy;
} dp
[4];
char a
;
int vis
[4];
int len;
int Min(int b,int c,int d)
{
if(b>c) b=c;
return b<d?b:d;
}
int Max(int b,int c,int d)
{
if(b<c) b=c;
return b>d?b:d;
}
Node dfs(int k,int f)
{
if(vis[k][f]) return dp[k][f];
vis[k][f]=1;
dp[k][f].minx=dp[k][f].maxx=dp[k][f].miny=dp[k][f].maxy=0;
if(k==len-1)
{
if(a[k]=='F')
{
if(f==0) dp[k][f].maxy=1,dp[k][f].miny=1;
else if(f==1) dp[k][f].maxy=-1,dp[k][f].miny=-1;
else if(f==2) dp[k][f].minx=-1,dp[k][f].maxx=-1;
else dp[k][f].minx=1,dp[k][f].maxx=1;
}
else if(a[k]=='?')
{
if(f==0) dp[k][f].maxy=1;
else if(f==1) dp[k][f].miny=-1;
else if(f==2) dp[k][f].minx=-1;
else dp[k][f].maxx=1;
}
}
else
{
if(a[k]=='L')
{
if(f==0) dp[k][f]=dfs(k+1,2);
else if(f==1) dp[k][f]=dfs(k+1,3);
else if(f==2) dp[k][f]=dfs(k+1,1);
else dp[k][f]=dfs(k+1,0);
}
else if(a[k]=='R')
{
if(f==0) dp[k][f]=dfs(k+1,3);
else if(f==1) dp[k][f]=dfs(k+1,2);
else if(f==2) dp[k][f]=dfs(k+1,0);
else dp[k][f]=dfs(k+1,1);
}
else if(a[k]=='F')
{
if(f==0)
{
dp[k][f]=dfs(k+1,0);
dp[k][f].maxy++;
dp[k][f].miny++;
}
else if(f==1)
{
dp[k][f]=dfs(k+1,1);
dp[k][f].miny--;
dp[k][f].maxy--;
}
else if(f==2)
{
dp[k][f]=dfs(k+1,2);
dp[k][f].minx--;
dp[k][f].maxx--;
}
else
{
dp[k][f]=dfs(k+1,3);
dp[k][f].maxx++;
dp[k][f].minx++;
}
}
else
{
Node b,c,d,e;
if(f==0)
{
b=dfs(k+1,0);
b.maxy++; b.miny++;
c=dfs(k+1,2);
d=dfs(k+1,3);
dp[k][f].minx=Min(b.minx,c.minx,d.minx);
dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
dp[k][f].miny=Min(b.miny,c.miny,d.miny);
dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
}
else if(f==1)
{
b=dfs(k+1,1);
b.maxy--;  b.miny--;
c=dfs(k+1,3);
d=dfs(k+1,2);
dp[k][f].minx=Min(b.minx,c.minx,d.minx);
dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
dp[k][f].miny=Min(b.miny,c.miny,d.miny);
dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
}
else if(f==2)
{
b=dfs(k+1,2);
b.maxx--; b.minx--;
c=dfs(k+1,1);
d=dfs(k+1,0);
dp[k][f].minx=Min(b.minx,c.minx,d.minx);
dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
dp[k][f].miny=Min(b.miny,c.miny,d.miny);
dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
}
else
{
b=dfs(k+1,3);
b.maxx++; b.minx++;
c=dfs(k+1,0);
d=dfs(k+1,1);
dp[k][f].minx=Min(b.minx,c.minx,d.minx);
dp[k][f].maxx=Max(b.maxx,c.maxx,d.maxx);
dp[k][f].miny=Min(b.miny,c.miny,d.miny);
dp[k][f].maxy=Max(b.maxy,c.maxy,d.maxy);
}
}
}
return dp[k][f];
}
int main()
{
int cas=1;
while(~scanf("%s",a))
{
len=strlen(a);
memset(vis,0,sizeof(vis));
Node ans=dfs(0,3);
printf("Case %d: %d %d %d %d\n",cas++,ans.minx,ans.maxx,ans.miny,ans.maxy);
}
return 0;
}

代码2:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: