1+ #include < cstdio>
2+ #include < cstring>
3+ #include < cassert>
4+
5+ const int UP = 0 ;
6+ const int LEFT = 1 ;
7+ const int RIGHT = 2 ;
8+ const int DOWN = 3 ;
9+
10+ const int maxn = 70 + 5 ;
11+
12+ // d[i][a][b][s] means the minimal future energy when you already tapped i notes
13+ // your left foot at a, right foot at b, last foot is s
14+ int d[maxn][4 ][4 ][3 ];
15+
16+ // if the optimal strategy is to move foot f(0~2) to position t, action=f*4+t
17+ int action[maxn][4 ][4 ][3 ];
18+
19+ char seq[maxn], pos[256 ], footch[] = " .LR" ;
20+
21+ // energy needed to move a foot FOR THE SECOND TIME, from a to ta
22+ int energy (int a, int ta) {
23+ if (a == ta) return 3 ;
24+ if (a + ta == 3 ) return 7 ; // across
25+ return 5 ; // adjacent
26+ }
27+
28+ int energy (int i, int a, int b, int s, int f, int t, int & ta, int & tb) {
29+ ta = a; tb = b;
30+ if (f == 1 ) ta = t;
31+ else if (f == 2 ) tb = t;
32+
33+ // check target arrows
34+ if (ta == tb) return -1 ;
35+ if (ta == RIGHT && tb == LEFT) return -1 ;
36+ if (a == RIGHT && tb != b) return -1 ; // you can't move you right foot before your left foot comes back
37+ if (b == LEFT && ta != a) return -1 ;
38+
39+ // compute energy
40+ int e;
41+ if (f == 0 ) e = 0 ; // no move
42+ else if (f != s) e = 1 ; // alternative foot, low energy
43+ else {
44+ if (f == 1 ) e = energy (a, ta);
45+ else e = energy (b, tb);
46+ }
47+ return e;
48+ }
49+
50+ // update state (i,a,b,s). foot f is moved to t
51+ void update (int i, int a, int b, int s, int f, int t) {
52+ int ta, tb;
53+ int e = energy (i, a, b, s, f, t, ta, tb);
54+ if (e < 0 ) return ; // invalid
55+
56+ int cost = d[i+1 ][ta][tb][f] + e;
57+ int & ans = d[i][a][b][s];
58+ if (cost < ans) {
59+ ans = cost;
60+ action[i][a][b][s] = f * 4 + t;
61+ }
62+ }
63+
64+ int main () {
65+ pos[' U' ] = 0 ; pos[' L' ] = 1 ; pos[' R' ] = 2 ; pos[' D' ] = 3 ;
66+
67+ while (scanf (" %s" , seq) == 1 ) {
68+ if (seq[0 ] == ' #' ) break ;
69+ int n = strlen (seq);
70+ memset (d, 0 , sizeof (d));
71+ for (int i = n-1 ; i >= 0 ; i--)
72+ for (int a = 0 ; a < 4 ; a++)
73+ for (int b = 0 ; b < 4 ; b++) if (a != b)
74+ for (int s = 0 ; s < 3 ; s++) {
75+ d[i][a][b][s] = 10 *n;
76+ if (seq[i] == ' .' ) {
77+ update (i, a, b, s, 0 , 0 ); // no move
78+ for (int t = 0 ; t < 4 ; t++) {
79+ update (i, a, b, s, 1 , t); // move left foot
80+ update (i, a, b, s, 2 , t); // move right foot
81+ }
82+ } else {
83+ update (i, a, b, s, 1 , pos[seq[i]]); // move left foot
84+ update (i, a, b, s, 2 , pos[seq[i]]); // move right foot
85+ }
86+ }
87+
88+ // print solution
89+ int a = LEFT, b = RIGHT, s = 0 ; // d[0][1][2][0] is out answer
90+ for (int i = 0 ; i < n; i++) {
91+ int f = action[i][a][b][s] / 4 ;
92+ int t = action[i][a][b][s] % 4 ;
93+ printf (" %c" , footch[f]);
94+ s = f;
95+ if (f == 1 ) a = t;
96+ else if (f == 2 ) b = t;
97+ }
98+ printf (" \n " );
99+ }
100+ return 0 ;
101+ }
0 commit comments