AtCoder Biginner Contest 099 C Strange Bank
なかなかおもしろい問題が出たので、主な考察の流れを書いておこうかなと思います
問題
https://abc099.contest.atcoder.jp/tasks/abc099_c
ある銀行では、お金の引き出しを難しくするために、一回の操作で引き出せる金額が以下のいずれかとなっています。 1 円 6 円、6^2(=36) 円、6^3(=216) 円、… 9 円、9^2(=81) 円、9^3(=729) 円、… この銀行からちょうど N 円を引き出すには少なくとも何回の操作が必要か求めてください。 ただし、一度引き出したお金を再び預け入れてはならないとします。 1 <= N <= 100000
考察
自分が意識していることの一つに、
「一気に二つのことをしようとするな」
なので、これも
「一気に6nと9nを扱おうとするな」
と考えて解きました(状態をうまく縮約できるときもありますが、難しい場合が多い(それはAGC))
それぞれで考えます
6nだけ使える場合
このときは N を6進数で表示したときの桁の総和が答えです
9nだけ使える場合
このときは N を9進数で表示したときの桁の総和が答えです
これを踏まえると....
6進数で扱う分と9進数で扱う分で分けてそれぞれの総和を足せばイケそう...?
となるのでそれをします
O(NlogN)で解くことができましたね
https://abc099.contest.atcoder.jp/submissions/2649449
クソコード
#include <bits/stdc++.h> using namespace std; using i64 = long long; #define rep(i,s,e) for(int (i) = (s);(i) <= (e);(i)++) int N; int main(){ cin >> N; int result = N; for(int n = 0;n <= N;n++){ int nn = n; int m = N - n; int ans = 0; int nine = 1; while(nine * 9 <= nn) nine *= 9; while(nine != 1){ ans += nn / nine; nn %= nine; nine /= 9; } ans += nn; nn = m; nine = 1; while(nine * 6 <= nn) nine *= 6; while(nine != 1){ ans += nn / nine; nn %= nine; nine /= 6; } ans += nn; result = min(ans , result); } cout << result << endl; }