fork download
#include <iostream>
#include <vector>
#include <cmath>
#include <cassert>

using namespace std;

vector<unsigned long long> a(101,0);

// O(N) . Простой перебор. Для данного N перебираем
// все возможные разбиения числа на два слагаемых.
// Получаем две задачи меньшего размера. Решив их
// , собираем решение исходной выбрав то
// которое дает наибольшее произведение
unsigned long long task128_helper(unsigned int n) {
    if (a[n]) {
        return a[n];
    }
    for (unsigned int i = 1; i <= n/2; ++i) {
        a[n] = max(a[n], task128_helper(i)*task128_helper(n-i));
    }
    return a[n];
}

unsigned long long task128(unsigned int n){
    if (n) {
        return a[n] ? a[n] : task128_helper(n);
    }
    return 0;
}

// Посмотрев на то что получилось на выходе предыдущего алгоритма
// можно заметить что решения имеют вид 3^n*2^k. Это должно иметь под
// собой какое-то обоснование. Для начала поймем почему другие слагаемые не нужны.
// Например возмем 5. Если 5 разложить на сумму 3 и 2 , то видно что в таком случае
// произведение равно шести и вообще n <= 2^(n/2) и n <= 3^(n/3). Далее, функция
// 2*2*2...3*3 возрастает по мере увеличения числа троек. Из этого можно сделать
// вывод что нам выгоднее иметь как можно больше троек.
// Итак осталось только решить , что делать когда число не делится на 3
// Остаток 2 - Тут все просто просто берем эту двойку
// Остаток 1 - Уберем одну тройку и возьмем две двойки потому что 2*2>3*1
unsigned long long task128_fast(unsigned int n) {
    unsigned long long mult = 1;

    switch (n % 3) {
        case 1:
            mult = 4;
            n -= mult;
            break;
        case 2:
            mult = 2;
            n -= mult;
            break;
        default:
            mult = 1;
            break;
    }

    unsigned int k = n / 3;
    return mult * (unsigned long long)pow(3, k);
}

int main() {
    a[0] = 0;
    a[1] = 1;
    a[2] = 2;
    a[3] = 3;

    for(int i = 4; i < 101; ++i) {
        auto a = task128(i);
        auto b = task128_fast(i);
        cout << i << " -> " << a << " -> " << b << endl;
        assert(a == b);
    }

    return 0;
}
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
4 -> 4 -> 4
5 -> 6 -> 6
6 -> 9 -> 9
7 -> 12 -> 12
8 -> 18 -> 18
9 -> 27 -> 27
10 -> 36 -> 36
11 -> 54 -> 54
12 -> 81 -> 81
13 -> 108 -> 108
14 -> 162 -> 162
15 -> 243 -> 243
16 -> 324 -> 324
17 -> 486 -> 486
18 -> 729 -> 729
19 -> 972 -> 972
20 -> 1458 -> 1458
21 -> 2187 -> 2187
22 -> 2916 -> 2916
23 -> 4374 -> 4374
24 -> 6561 -> 6561
25 -> 8748 -> 8748
26 -> 13122 -> 13122
27 -> 19683 -> 19683
28 -> 26244 -> 26244
29 -> 39366 -> 39366
30 -> 59049 -> 59049
31 -> 78732 -> 78732
32 -> 118098 -> 118098
33 -> 177147 -> 177147
34 -> 236196 -> 236196
35 -> 354294 -> 354294
36 -> 531441 -> 531441
37 -> 708588 -> 708588
38 -> 1062882 -> 1062882
39 -> 1594323 -> 1594323
40 -> 2125764 -> 2125764
41 -> 3188646 -> 3188646
42 -> 4782969 -> 4782969
43 -> 6377292 -> 6377292
44 -> 9565938 -> 9565938
45 -> 14348907 -> 14348907
46 -> 19131876 -> 19131876
47 -> 28697814 -> 28697814
48 -> 43046721 -> 43046721
49 -> 57395628 -> 57395628
50 -> 86093442 -> 86093442
51 -> 129140163 -> 129140163
52 -> 172186884 -> 172186884
53 -> 258280326 -> 258280326
54 -> 387420489 -> 387420489
55 -> 516560652 -> 516560652
56 -> 774840978 -> 774840978
57 -> 1162261467 -> 1162261467
58 -> 1549681956 -> 1549681956
59 -> 2324522934 -> 2324522934
60 -> 3486784401 -> 3486784401
61 -> 4649045868 -> 4649045868
62 -> 6973568802 -> 6973568802
63 -> 10460353203 -> 10460353203
64 -> 13947137604 -> 13947137604
65 -> 20920706406 -> 20920706406
66 -> 31381059609 -> 31381059609
67 -> 41841412812 -> 41841412812
68 -> 62762119218 -> 62762119218
69 -> 94143178827 -> 94143178827
70 -> 125524238436 -> 125524238436
71 -> 188286357654 -> 188286357654
72 -> 282429536481 -> 282429536481
73 -> 376572715308 -> 376572715308
74 -> 564859072962 -> 564859072962
75 -> 847288609443 -> 847288609443
76 -> 1129718145924 -> 1129718145924
77 -> 1694577218886 -> 1694577218886
78 -> 2541865828329 -> 2541865828329
79 -> 3389154437772 -> 3389154437772
80 -> 5083731656658 -> 5083731656658
81 -> 7625597484987 -> 7625597484987
82 -> 10167463313316 -> 10167463313316
83 -> 15251194969974 -> 15251194969974
84 -> 22876792454961 -> 22876792454961
85 -> 30502389939948 -> 30502389939948
86 -> 45753584909922 -> 45753584909922
87 -> 68630377364883 -> 68630377364883
88 -> 91507169819844 -> 91507169819844
89 -> 137260754729766 -> 137260754729766
90 -> 205891132094649 -> 205891132094649
91 -> 274521509459532 -> 274521509459532
92 -> 411782264189298 -> 411782264189298
93 -> 617673396283947 -> 617673396283947
94 -> 823564528378596 -> 823564528378596
95 -> 1235346792567894 -> 1235346792567894
96 -> 1853020188851841 -> 1853020188851841
97 -> 2470693585135788 -> 2470693585135788
98 -> 3706040377703682 -> 3706040377703682
99 -> 5559060566555523 -> 5559060566555523
100 -> 7412080755407364 -> 7412080755407364