题目链接: UVA10618 POJ1726 ZOJ2120
【题意】
【分析】
虽然看起来似乎蛮简单,但是自己写的时候错了无数次,唉,具体看代码吧
【AC代码】 UVA15ms POJ32ms ZOJ 0ms
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 75
#define INF 0x3f3f3f3f
struct NODE{
int i, l, r, s;
}path[MAXN][4][4][3];
char a[MAXN];
int dp[MAXN][4][4][3], n, buf;//箭头:0-上,1-下,2-左,3-右
//dp[i][a][b][s]表示前i时刻,左脚在a箭头,右脚在b箭头,上一次哪只脚移动了s(0没移动,1左脚移动,2右脚移动)
bool ok(int f, int l, int r, int to)//这里的f用0表示左,1表示右,判断本次移动是否合法
{
if (0 == f)
{
if (to == r) return false;
if (to == l) return true;
if (2 == r) return false;
}
else
{
if (to == l) return false;
if (to == r) return true;
if (3 == l) return false;
}
return true;
}
int cost(int s, int now, int from, int to)//这里的s,now都是1表示左,2表示右
{
if (s != now) return 1;
if (from == to) return 3;
if ((from == 0 && to == 1) || (from == 1 && to == 0)) return 7;
if ((from == 2 && to == 3) || (from == 3 && to == 2)) return 7;
return 5;
}
int dfs(int i, int l, int r, int s)
{
int& ans = dp[i][l][r][s];
NODE& p = path[i][l][r][s];
if (-1 != ans) return ans;
if (i == n) return ans = 0;
ans = INF;
if ('.' == a[i])
{
ans = min(ans, dfs(i+1,l,r,0));//不需要踩也不需要移动
p.i = i + 1, p.l = l, p.r = r, p.s = 0;
for (int j = 0; j < 4; j++)
{
if (ok(0, l, r, j))//左脚移动到j箭头
{
buf = dfs(i + 1, j, r, 1) + cost(s,1,l, j);
if (ans > buf)
ans = buf, p.i = i + 1, p.l = j, p.r = r, p.s = 1;
}
if (ok(1, l, r, j))//右脚移动到j
{
buf = dfs(i + 1, l, j, 2) + cost(s,2,r, j);
if (ans > buf)
ans = buf, p.i = i + 1, p.l = l, p.r = j, p.s = 2;
}
}
return ans;
}
int to;
switch (a[i])
{
case 'U':to = 0; break;
case 'D':to = 1; break;
case 'L':to = 2; break;
case 'R':to = 3; break;
}
if (ok(0, l, r, to))//左脚移动到to
{
buf = dfs(i + 1, to, r, 1) + cost(s,1,l, to);
if (ans > buf)
ans = buf, p.i = i + 1, p.l = to, p.r = r, p.s = 1;
}
if (ok(1, l, r, to))//右脚移动到to
{
buf = dfs(i + 1, l, to, 2) + cost(s,2,r, to);
if (ans > buf)
ans = buf, p.i = i + 1, p.l = l, p.r = to, p.s = 2;
}
return ans;
}
void pt(int i, int l, int r, int s)
{
if (n == i) return;
NODE& p = path[i][l][r][s];
if (!p.s)
printf(".");
else if (p.s == 1)
printf("L");
else
printf("R");
pt(p.i, p.l, p.r, p.s);
}
int main()
{
#ifdef SHY
freopen("e:\\1.txt", "r", stdin);
#endif
while(scanf("%s%*c", a) && '#' != a[0])
{
n = strlen(a);
memset(dp,-1,sizeof(dp));
dfs(0, 2, 3, 0);
pt(0, 2, 3, 0);
puts("");
}
return 0;
}