SRM682 D2H FriendlyRobot

文字列の命令で動くロボットがある.この文字列を回書き換えられることが出来るときに,最大で何回を通ることが出来るか.


移動回数が奇数回の時にに戻ることは出来ない.また偶数回の場合でも横方向,縦方向の移動量が共に偶数回,共に奇数回の場合のみ戻ることが出来る.
また,に変えることで移動量が変わる.
そして,戻るために命令を書き換えなければならない回数も以下のように一意に求まる.

共に奇数回の場合にされるのは,例えば命令がの場合にに書き換えることでに戻れるためである.

これより

として,総当りしてmaxを取った.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public:
int findMaximumReturns(string s, int K) {

  vector<int> X(s.size() + 1), Y(s.size() + 1);
  int x = 0, y = 0;
  rep(i, s.size()) {
      if(s[i] == 'U') y++;
      if(s[i] == 'D') y--;
      if(s[i] == 'R') x++;
      if(s[i] == 'L') x--;

      X[i+1] = x; Y[i+1] = y;
  }

  rep(i, s.size() + 1) {
      rep(j, K + 1) {
          dp[i][j] = -1;
      }
  }
  dp[0][0] = 0;

  rep(i, s.size() + 1) {
      rep(j, K + 1) {
          if(dp[i][j] == -1) continue;
          for(int k = i + 2; k < s.size() + 1; k += 2) {
              int s = abs(X[k] - X[i]), t = abs(Y[k] - Y[i]);
              int res = 0;

              if(s % 2 == 0 && t % 2 == 1) continue;
              if(s % 2 == 1 && t % 2 == 0) continue;
              if(s % 2 == 0 && t % 2 == 0) res = s / 2 + t / 2;
              if(s % 2 == 1 && t % 2 == 1) res = s / 2 + t / 2 + 1;

              if(j + res > K) continue;
              dp[k][j + res] = max(dp[k][j + res], dp[i][j] + 1);
          }
      }
  }

  ll ans = 0;
  rep(i, s.size() + 1) {
      rep(j, K + 1) {
          ans = max(ans, dp[i][j]);
      }
  }

  return ans;
}
Feb 29th, 2016