はまやんはまやんはまやん

hamayanhamayan's blog

When I hit my pocket... [ 「みんなのプロコン 2019」 C]

https://atcoder.jp/contests/yahoo-procon2019-qual/tasks/yahoo_procon2019_qual_c

解説

https://atcoder.jp/contests/yahoo-procon2019-qual/submissions/4207345

交換操作をするためにはA枚にはする必要があるので、A枚までは叩いて増やそう。
この過程で操作回数が尽きたら終了。
以降、KからA枚にするまでに必要な操作回数を引いて考える。
 
ここから、場合分けする。
ビスケットA枚を1円にして、1円をビスケットB枚にすると、2回の操作でB-A枚の儲けがあったことになる。
2回叩いて増やすと、2枚の儲けなので、2≦B-Aを満たすなら、交換操作をしたほうがいいことになる。
よって、A+2≦Bかどうかで場合分けしよう。
交換操作をしたほうがいいなら、なるべく交換する。
K/2の切り捨てが最大交換回数cntとなる。
1回でB-Aだけ得するので、cnt*(B-A)だけ得することになる。
Kが1だけ余るなら、叩いて増やす。
 
そうじゃない場合は交換操作より叩いて増やすほうが効率がいいので、ひたすら叩いて増やす。

ll K, A, B;
//---------------------------------------------------------------------------------------------------
ll solve() {
    ll have = 1;
 
    // A枚までは叩く必要がある
    ll a = min(K, A - 1);
    have += a;
    K -= a;
    if (K == 0) return have;
 
    // なるべく交換する
    if (A + 2 <= B) {
        ll cnt = K / 2;
        have += cnt * (B - A);
        if (K % 2 == 1) have++;
        return have;
    }
    else {
        return have + K;
    }
}
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> K >> A >> B;
    cout << solve() << endl;
}