質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

883閲覧

Atcoder: D - Alter Altarのアルゴリズム

Nippun

総合スコア1147

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/08/02 15:43

Alter Altarの問題ですが

Python

1n = int(input()) 2C = input() 3print(C[:C.count('R')].count("W"))

で解けるみたいなのですがアルゴリズムがよくわかりません。
どうしてRの個数までの部分配列の中のWの数を求めると最小回数になるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

最終的な石の並び順が「赤い石は左側に、白い石は右側に集める」状態(つまり、RR...RRWW...WWW)にならなければならないことについては、swordoneさんのご回答およびAtCoder公式解説のとおりです。

それを前提とした上でご説明します。
なお、以下はどちらかというと直感的な説明であり、数学的に厳密な証明にはなっていないかもしれません。

まず、問題文では、

  • 入れ替え:石を2個選び (隣り合っていなくてもよい)、それらを入れ替える。
  • 色変え:石を1個選び、その石の色を変える (赤なら白に、白なら赤に)。

の2つの操作が定義されていますが、この問題においては、実は、色変えの操作は無視することができます。

なぜなら、「任意の色変え操作について、それと比較して同等またはより有利な(=最終的な手数が増えない)入れ替え操作が存在する」ということが言えるからです。

具体的には、例えば、「ある赤い石(Xとする)を一つ選び、その石を白に変える」という操作を行う代わりに、「赤い石Xと、Xよりも左にある白い石Yを入れ替える」ことにしても、不利になる(最終的な手数が増える)ことはありません。
(この点について、私も厳密な証明はできないのですが、色変えの代わりに入れ替えを行うことにより、「赤い石X(の位置にある石)を白に変える」ことに加えて「左にある邪魔な(白い石はなるべく右にあったほうが最終形に近づくという意味で、左にある白い石は邪魔です)白い石Y(の位置にある石)を赤に変える」ことを同時に達成できるので、同等またはより有利になる、と考えると直感的には分かりやすいのではないかと思います。)

なお、白い石を赤に変える操作についても、上記と同様のことが言えます。
また、赤い石Xよりも左に白い石が一つもない状態であれば、そもそもそのようなXに対して操作を行う必要がないので、そのような場合を考える必要はありません。

以上を踏まえ、入れ替えの操作のみで、「赤い石は左側に、白い石は右側に集める」状態を達成する方法を考えます。
すると、操作の前後で赤い石及び白い石のそれぞれの総数は変わらないことになるので、「左から順に初期状態における赤い石の総数個だけ赤い石が並び、その右に初期状態における白い石の総数個だけ白い石が並んでいる」状態が最終形であることが分かります。
したがって、各手番ごとに「左から赤い石の総数個の範囲からはみ出している赤い石(Xとする)」を1つ選び、赤い石Xを「左から赤い石の総数個の範囲に存在する白い石」と入れ替える操作を行っていくのが最善となります。

ここで、

  • 1度の手番で「左から赤い石の総数個の範囲からはみ出している赤い石の数」を2以上減らすことはできない
  • 逆に、各手番において上記の操作を行えなくなることはない(なぜなら、上記の操作を行えないということは、どの赤い石についても自分より左に白い石が存在しない状態になっているということにほかならず、それはつまり最終形に到達しているということなので)

ということが言えます。

したがって、最適な操作を行ったとき、各手番ごとに「左から赤い石の総数個の範囲に収まっていない赤い石の数」は1ずつ減っていくことになるので、「Rの個数までの部分配列の中のWの数」(これは、「左から赤い石の総数個の範囲からはみ出している赤い石の数」と一致します)が操作の最小回数に一致します。

投稿2020/08/03 05:00

編集2020/08/03 05:19
mysk

総合スコア9

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nippun

2020/08/03 13:43

なるほどです!! 複雑そうに見えて実は単純ですね ありがとうございます。
guest

0

赤い石の左に白い石があってはいけないので、赤い石は左側に、白い石は右側に集めることになります。
つまり、「色変え」をしない場合、最終的に左から赤の個数分、赤で連続している必要があります。
そのためには、その範囲にある白い石を、範囲外にある赤い石と入れ替える必要があります。
例えば、次のような場合

plain

1RRWWWRWRWWRR

赤Rは6個あり、左から6個目までに白Wは3個あります。このW3個を、左から7番目~12番目にあるR3個と入れ替えれば、「赤い石は左側に、白い石は右側に集める」状態になります。
「色変え」で手数が少なくなるかについての議論はちょっとわからないのでパスします。

投稿2020/08/02 16:03

swordone

総合スコア20669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Nippun

2020/08/03 13:43

ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問