Problem:
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});

E: 28

問題文

トランプゲームの大富豪において，ランクが $2$, $8$ のカードは強力です．
そこで，$10$ 進数表記で数字の $2$, $8$ のみからなる整数を良い整数と呼ぶことにします．
良い整数を小さいものから列挙すると $2, 8, 22, 28, 82, 88, \cdots$ となります．

$n$ を正の整数とします．$n$ が良い整数の積の形で表現できるとき，
最大でいくつの積になるか求めてください．できないなら $-1$ と出力してください．

入力

$n$

制約

$1 \leq n \leq 10^{18}$

出力

答えを $1$ 行で出力してください．

サンプル

サンプル入力1

1

サンプル出力1

-1

サンプル入力2

2

サンプル出力2

1

サンプル入力3

88

サンプル出力3

3

$2 \times 2 \times 22$ と表せます．

サンプル入力4

100

サンプル出力4

-1

サンプル入力5

173553147234869248

サンプル出力5

11

$2^6 \times 28 \times 2222^3 \times 8828$ と表せます．

Solution in C++11 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

typedef long long int ll;
const ll INF = 1LL << 28;

ll N;
vector<ll> num;
map<ll,ll> memo;
queue<ll> q;
function<ll(ll)> seki;

int main() {
    cin >> N;
    q.push(2LL); q.push(8LL);
    while (q.size()) {
        ll n = q.front(); q.pop();
        num.push_back(n);
        if (n <= 1e18) {
            q.push(n * 10LL + 8LL);
            q.push(n * 10LL + 2LL);
        }
    }


    sort(num.begin(), num.end());
    
    seki = [&](ll n) -> ll {
        if (memo.find(n) != memo.end()) return memo[n];

        int i = (int)(lower_bound(num.begin(), num.end(), n) - num.begin());
        memo[n] = -INF;
        if (num[i] == n) memo[n] = 1;
        for (; i > -1; i--) {
            if (n % num[i] == 0 ) {
                memo[n] = max(memo[n], seki(n / num[i]) + seki(num[i]));
            }
        }


        return memo[n];
    };

    int ans = seki(N);
    if (ans > 0) cout << ans << endl;
    else cout << -1 << endl;

    return 0;
}