Official

A - Apple Editorial by Nyaan


\(1\)\(X\) 円, \(3\)\(Y\) 円」というフレーズはスーパーでよく見かける身近な言い回しです。
このような状況で出てくる「\(1\) 円でも安く目的のものを買う方法」をアルゴリズムとして表現してみましょう。すると次のようになります。

  1. \(3\)\(Y\) 円」の方が「\(1\)\(X\) 円を\(3\) 回」より安い場合

    • できるだけ「\(3\)\(Y\) 円」の方でりんごを買う。端数が出たら「 \(1\)\(X\) 円」で買う。
  2. \(1\)\(X\) 円を \(3\) 回」の方が 「\(3\)\(Y\) 円」より安い、あるいはどちらでも変わらない場合

    • \(N\) 個すべて「\(1\)\(X\) 円」の方でりんごを買う。

このアルゴリズムは最適であることが数学的にも証明できます。よってこれを実装すればよいです。
2 番目の場合分けの方は答えが \(XN\) 円になるので実装は楽だと思います。
1 番目の場合分けの方は除算を利用して実装するのが簡明です。\(N\)\(3\) で割った商を \(Q\), あまりを \(R\) とすると、1 番目の場合分けでは 「\(3\)\(Y\) 円」を \(Q\) 回、「\(1\)\(X\) 円」を \(R\) 回使うのが最適になります。\(Q, R\) は除算を計算する演算子を利用して(C++ の場合) N / 3, N % 3 で計算することができます。(for 文や while 文などのループを用いたシミュレーションで計算する方法もあります。)

以上よりこの問題を解くことができました。計算量は \(\mathrm{O}(1)\) です。(シミュレーションを利用する場合は \(\mathrm{O}(N)\) )

  • 実装例(C++)
#include <iostream>
using namespace std;
int main() {
  int X, Y, N;
  cin >> X >> Y >> N;
  if (X * 3 > Y) {
    cout << (N / 3) * Y + (N % 3) * X << endl;
  } else {
    cout << X * N << endl;
  }
}

posted:
last update: