1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AtCoder ARC002 C-コマンド入力 の嘘解法について

Last updated at Posted at 2020-06-06

はじめに

 嘘解法がある問題について、古い問題ということもあり解説が少ないため解説記事を書きます。
 特に、自分が用いているPython言語での解説がネット上に見当たらず苦労したので、
 Python言語でのソースコードともに解説します。

問題

 問題文
  ARC002 C-コマンド入力
 解説
  公式解説
#嘘解法
 L,Rを列挙し、L,Rどちらかから順に貪欲に置換する、を全通り試す。
 この解法では入力が

8
ABABBABA

 のようなケースで誤りになることが公式解説において説明されています。
 正解はL=AB,R=BAとすればLLRRと出来るので「4」ですが、
 嘘解法ですと、LLBLAあるいはARBRRとなって「5」となってしまいます。
 ただしこのようなケースがテスト項目に入っていないため、嘘解法でもACになります。

#正しい解法
 公式解説にある通り、動的計画法を用います。
 自分は、i文字目を
 ・(j=0) L,Rで置き換えない場合の文字数
 ・(j=1) Lで置き換えられて、置き換えた場合の文字数
 ・(j=2) Rで置き換えられて、置き換えた場合の文字数
 という3状態を作って解きました。
 このdp表を dp[j][i]と書いています。

 dp[0][i]は、1文字前の時点での文字数の最小値に+1した値です。

dp[0][i]= min(dp[0][i-1],dp[1][i-1],dp[2][i-1])+1

 dp[1][i]およびdp[2][i]は、i-1文字目とi文字目をLあるいはRで置き換えるわけですから、i-2文字目までの文字数の最小値に+1した文字数となります。

if c[i-2:i]==L:
dp[1][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1
if c[i-2:i]==R:
dp[2][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1

 i-1文字目とi文字目がL,Rでなく置き換えられない場合は
 ・dp[0][i]をコピーしておく
 か
 ・答えよりも大きい値を入れておく(Nとかfloat("inf")とか)
 としておきましょう。
 動的計画法によって最小値を取っていくので、dp[0][i]以上の値が何か入っていれば問題ありません。

#サンプルコード(Python)

N=int(input())
c=input()

L_list=["AA","AB","AX","AY","BA","BB","BX","BY","XA","XB","XX","XY","YA","YB","YX","YY"]
R_list=["AA","AB","AX","AY","BA","BB","BX","BY","XA","XB","XX","XY","YA","YB","YX","YY"]

ans=N
for L in L_list:
  for R in R_list:
    dp= [[0]*(N+1) for _ in range(3)]  #初期値として0を代入していますが、本当は大きい値や文字数(i)を代入した方がこの後簡単に書けます

    for i in range(1,N+1):
      dp[0][i]= min(dp[0][i-1],dp[1][i-1],dp[2][i-1])+1
      if i==1:
        dp[1][i]= 1
        dp[2][i]= 1
      else:
        if c[i-2:i]==L:
          dp[1][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1
          dp[2][i]=N
        elif c[i-2:i]==R:
          dp[1][i]=N
          dp[2][i]=min(dp[0][i-2],dp[1][i-2],dp[2][i-2])+1
        else:
          dp[1][i]=N
          dp[2][i]=N

    tmp=min(dp[0][-1],dp[1][-1],dp[2][-1])
    ans=min(ans,tmp)

print(ans)

#関連リンク
 C++での解説記事を書かれている方
  忘れても大丈夫

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?