一开始偷懒没读原题,根据白书里的描述似懂非懂的做了,WA了还纳闷半天。最好还是先读原题啊,有些看似无用的句子会给很多有用的信息
每个决策要受到几个因素的影响:1、当前时间 2、左脚位置 3、右脚位置 4、上一次动了哪只脚
前三个因素比较intuitive。第4个因素来自题目中的叙述:如果这次动的脚和上次的不同,则只消耗1个能量。如果这次和上次动的是同一只脚,则分三种情况,分别对应3、5、7个能量。所以上次动的脚也应该包含在状态中。
除了状态的设计,还要看一下哪些情况下状态不能转移,要注意细节。
Run Time: 0.032s
#define UVa "LT9-18.10618.cpp" //Tango Tango Insurrection
char fileIn[30] = UVa, fileOut[30] = UVa;
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
//Global Variables. Reset upon Each Case!
const int maxn = 70 + 5, INF = 99999999;
const int DIRUP = 0, DIRRIGHT = 1, DIRDOWN = 2, DIRLEFT = 3;
const int FTLEFT = 1, FTRIGHT = 2, FTSTILL = 0;
int DIR[300];
char FOOT[3];
char line[maxn];
int s[maxn];
int n;
int d[maxn][4][4][3];
int act[maxn][4][4][3];
/
int non_still_energy(int p, int tp) {
if(abs(p-tp) == 2) return 7;
else if(p == tp) return 3;
return 5;
}
int energy(int u, int l, int r, int tl, int tr, int move, int prev) {
if(move == FTSTILL)
return 0;
if(prev != move) return 1;
else if(move == FTLEFT)
return non_still_energy(l, tl);
else
return non_still_energy(r, tr);
}
void update(int& ans, int& action, int u, int l, int r, int tl, int tr, int move, int prev) {
if(tl != l || tr != r) {
if(tl == r || tr == l) return;
if(tl == DIRRIGHT && tr == DIRLEFT) return;
if(l == DIRRIGHT && move != FTLEFT) return;
if(r == DIRLEFT && move != FTRIGHT) return;
}
int& ans_v = d[u+1][tl][tr][move];
int e = energy(u, l, r, tl, tr, move, prev);
if(ans_v + e < ans) {
ans = ans_v + e;
action = 100*tl + 10*tr + move;
}
}
void print_ans() {
int l = DIRLEFT, r = DIRRIGHT, m = 0;
for(int u = 0; u < n; u ++) {
int action = act[u][l][r][m];
l = action/100;
r = (action/10)%10;
m = action%10;
printf("%c", FOOT[m]);
}
printf("\n");
}
int dp() {
for(int u = n-1; u >= 0; u --) { //notice the boundary
for(int l = 0; l < 4; l ++) {
for(int r = 0; r < 4; r ++) {
for(int m = 0; m < 3; m ++) {
int &ans = d[u][l][r][m], &action = act[u][l][r][m];
ans = INF;
if(s[u] == -1) { //empty note
update(ans, action, u, l, r, l, r, FTSTILL, m);
for(int i = 0; i < 4; i ++) {
update(ans, action, u, l, r, i, r, FTLEFT, m);
update(ans, action, u, l, r, l, i, FTRIGHT, m);
}
}
else {
update(ans, action, u, l, r, s[u], r, FTLEFT, m);
update(ans, action, u, l, r, l, s[u], FTRIGHT, m);
}
}
}
}
}
print_ans();
}
int main() {
DIR['U'] = 0, DIR['R'] = 1, DIR['D'] = 2, DIR['L'] = 3, DIR['.'] = -1;
FOOT[FTLEFT] = 'L', FOOT[FTRIGHT] = 'R', FOOT[FTSTILL] = '.';
while(scanf("%s", line) && line[0] != '#') {
n = strlen(line);
for(int i = 0; i < n; i ++) s[i] = DIR[line[i]];
memset(d, 0, sizeof(d));
memset(act, -1, sizeof(-1));
dp();
}
return 0;
}