A - Apple Editorial by Nyaan
「\(1\) 個 \(X\) 円, \(3\) 個 \(Y\) 円」というフレーズはスーパーでよく見かける身近な言い回しです。
このような状況で出てくる「\(1\) 円でも安く目的のものを買う方法」をアルゴリズムとして表現してみましょう。すると次のようになります。
「\(3\) 個 \(Y\) 円」の方が「\(1\) 個 \(X\) 円を\(3\) 回」より安い場合
- できるだけ「\(3\) 個 \(Y\) 円」の方でりんごを買う。端数が出たら「 \(1\) 個 \(X\) 円」で買う。
「\(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: