fork download
  1. #include <iostream>
  2. #include <unordered_map>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. using ull = unsigned long long;
  8.  
  9. struct pair_hash
  10. {
  11. template <typename T1, typename T2>
  12. std::size_t operator ()(const std::pair<T1, T2>& pair) const
  13. {
  14. return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
  15. }
  16. };
  17.  
  18. using TMem = std::unordered_map<std::pair<int,int>, ull, pair_hash>;
  19.  
  20. // Количество разложений для N блоков равно сумме количеств
  21. // разложений ,где максимальная длина нижнего уровня уровня
  22. // равна N-1,N-2,....
  23. struct task135_recurse
  24. {
  25. ull operator ()(int N)
  26. {
  27. return solve(N, N);
  28. }
  29.  
  30. private:
  31. ull solve(int N, int maxN)
  32. {
  33. ull result = 0;
  34.  
  35. if (N < 0) {
  36. return 0;
  37. }
  38.  
  39. if (N == 0) {
  40. return 1;
  41. }
  42.  
  43. for (int i = maxN; i > 0; --i) {
  44. result += solve(N - i, i - 1);
  45. }
  46.  
  47. return result;
  48. }
  49. };
  50.  
  51. // Оптимизация для предыдущего алгоритма. Запоминаем уже вычисленные
  52. // значения (мемоизация) чтобы не вычислять одно и тоже. По моим
  53. // замерам закэшировать удается до 90% значений
  54. struct task135_recurse_memo
  55. {
  56. ull operator ()(int N)
  57. {
  58. TMem mem;
  59. return solve(N, N, mem);
  60. }
  61.  
  62. std::pair<ull, ull> GetStats()
  63. {
  64. return make_pair(Calls, Hits);
  65. }
  66.  
  67. private:
  68. ull solve(int N, int maxN, TMem& mem)
  69. {
  70. auto it = mem.find(std::make_pair(N,maxN));
  71.  
  72. ++Calls;
  73. if (it != mem.end()) {
  74. ++Hits;
  75. return it->second;
  76. }
  77.  
  78. ull result = 0;
  79.  
  80. if (N == 0) {
  81. result = 1;
  82. }
  83.  
  84.  
  85. if (N > 0) {
  86. for (int i = maxN; i > 0; --i) {
  87. result += solve(N - i, i - 1, mem);
  88. }
  89. }
  90.  
  91. mem[std::make_pair(N,maxN)] = result;
  92.  
  93. return result;
  94. }
  95. private:
  96. ull Calls = 0;
  97. ull Hits = 0;
  98. };
  99.  
  100. // Здесь мы считаем туже формулу. Но на этот раз
  101. // идем нет от конца к началу , а от начала к концу
  102. // За счет этого избавляемся от рекурсии, но возможно
  103. // проигрываем по памяти и делаем возможно лишнюю работу
  104. // поскольку не знаем какие значения понадобятся потом
  105. struct task135_dynamic_array
  106. {
  107. ull operator ()(int N)
  108. {
  109. return solve(N);
  110. }
  111.  
  112. private:
  113. ull get(vector<vector<ull>>& a, int i, int j)
  114. {
  115. if (i < 0 || j < 0) {
  116. return 0;
  117. }
  118. return a[i][j];
  119. }
  120.  
  121. ull solve(int N)
  122. {
  123. vector<vector<ull>> a(N+1, vector<ull>(N+1));
  124.  
  125. for (int i = 0; i < N; ++i) {
  126. a[0][i] = 1;
  127. }
  128. for (int i = 1; i < N+1; ++i) {
  129. for (int j = 1; j < N+1; ++j) {
  130. for (int k = j; k > 0; --k) {
  131. a[i][j] += get(a, i - k, k - 1);
  132. }
  133. }
  134. }
  135. return a[N][N];
  136. }
  137. };
  138.  
  139.  
  140. // Определим решение немного иначе.
  141. // Количество разложений для N блоков равно сумме количеств
  142. // разложений двух типов
  143. // 1. на нижнем уровне лежит блок длины N
  144. // 2. на нижнем уровне лежит блок длины меньше N
  145.  
  146. struct task135_recurse1
  147. {
  148. ull operator ()(int N)
  149. {
  150. return solve(N, N);
  151. }
  152.  
  153. private:
  154. ull solve(int N, int maxN)
  155. {
  156. ull result = 0;
  157.  
  158. if (N < 0 || (maxN == 0 && N != 0)) {
  159. return 0;
  160. }
  161.  
  162. if (N == 0) {
  163. return 1;
  164. }
  165.  
  166. result += solve(N - maxN, maxN - 1) + solve(N, maxN - 1);
  167.  
  168. return result;
  169. }
  170. };
  171.  
  172. // Мемоизация предыдущего алгоритма. Опять не вычисляем уже
  173. // вычисленные значения. Для мойих тестов экономилось до 20%
  174. // вычислений (См. GetStats метод).
  175. struct task135_recurse_memo1
  176. {
  177. ull operator ()(int N)
  178. {
  179. TMem mem;
  180. return solve(N, N, mem);
  181. }
  182.  
  183. std::pair<ull, ull> GetStats()
  184. {
  185. return make_pair(Calls, Hits);
  186. }
  187.  
  188. private:
  189. ull solve(int N, int maxN, TMem& mem)
  190. {
  191. auto it = mem.find(std::make_pair(N,maxN));
  192.  
  193. ++Calls;
  194. if (it != mem.end()) {
  195. ++Hits;
  196. return it->second;
  197. }
  198.  
  199. ull result = 0;
  200.  
  201. if (N == 0 && maxN >= 0) {
  202. return 1;
  203. }
  204.  
  205. if (N > 0 && maxN > 0) {
  206. result += solve(N - maxN, maxN - 1, mem) + solve(N, maxN - 1, mem);
  207. }
  208.  
  209. mem[std::make_pair(N,maxN)] = result;
  210.  
  211. return result;
  212. }
  213. private:
  214. ull Calls = 0;
  215. ull Hits = 0;
  216. };
  217.  
  218. // Опять нерекурсивная динамика.
  219. // Одем от тачала к концу (от 1 к N)
  220. // За счет этого избавляемся от рекурсии,
  221. // но получаем избыточность по памяти и лишние вычисления
  222. // для ячеек которые возможно не будут нужны
  223. struct task135_dynamic_array1
  224. {
  225. ull operator ()(int N)
  226. {
  227. return solve(N);
  228. }
  229.  
  230. private:
  231. ull get(vector<vector<ull>>& a, int i, int j)
  232. {
  233. if (i < 0 || j < 0) {
  234. return 0;
  235. }
  236. return a[i][j];
  237. }
  238.  
  239. ull solve(int N)
  240. {
  241. vector<vector<ull>> a(N+1, vector<ull>(N+1));
  242.  
  243. for (int i = 0; i < N; ++i) {
  244. a[0][i] = 1;
  245. }
  246. for (int i = 1; i < N+1; ++i) {
  247. for (int j = 1; j < N+1; ++j) {
  248. a[i][j] = get(a, i-j,j-1) + get(a, i,j-1);
  249. }
  250. }
  251. return a[N][N];
  252. }
  253. };
  254.  
  255.  
  256. int main() {
  257.  
  258. // Прогоняем тесты для всех 6 реализаций задачи
  259. // вычисляем значение для всех значений от 1 до 100
  260. // печатаем и убеждаемся что все они совпадают
  261.  
  262. vector<ull> r1;
  263. for (int i = 1; i < 101; ++i) {
  264. r1.push_back(task135_recurse()(i));
  265. }
  266.  
  267. vector<ull> r2;
  268. for (int i = 1; i < 101; ++i) {
  269. auto a = task135_recurse_memo();
  270. r2.push_back(a(i));
  271. //cout << a.GetStats().first << " " << a.GetStats().second << endl;
  272. }
  273.  
  274. vector<ull> r3;
  275. for (int i = 1; i < 101; ++i) {
  276. r3.push_back(task135_recurse1()(i));
  277. }
  278.  
  279. vector<ull> r4;
  280. for (int i = 1; i < 101; ++i) {
  281. auto a = task135_recurse_memo1();
  282. r4.push_back(a(i));
  283. //cout << a.GetStats().first << " " << a.GetStats().second << endl;
  284. }
  285.  
  286. vector<ull> r5;
  287. for (int i = 1; i < 101; ++i) {
  288. r5.push_back(task135_dynamic_array()(i));
  289. }
  290.  
  291. vector<ull> r6;
  292. for (int i = 1; i < 101; ++i) {
  293. r6.push_back(task135_dynamic_array1()(i));
  294. }
  295.  
  296. for (int i = 0; i < 100; ++i) {
  297. cout << (i+1) << "-> " << r1[i] << " " << r2[i] << " " << r3[i] << " " << r4[i] << " " << r5[i] << " " << r6[i] << endl;
  298. }
  299.  
  300. return 0;
  301.  
  302. }
Success #stdin #stdout 0.7s 15256KB
stdin
Standard input is empty
stdout
1-> 1 1 1 1 1 1
2-> 1 1 1 1 1 1
3-> 2 2 2 2 2 2
4-> 2 2 2 2 2 2
5-> 3 3 3 3 3 3
6-> 4 4 4 4 4 4
7-> 5 5 5 5 5 5
8-> 6 6 6 6 6 6
9-> 8 8 8 8 8 8
10-> 10 10 10 10 10 10
11-> 12 12 12 12 12 12
12-> 15 15 15 15 15 15
13-> 18 18 18 18 18 18
14-> 22 22 22 22 22 22
15-> 27 27 27 27 27 27
16-> 32 32 32 32 32 32
17-> 38 38 38 38 38 38
18-> 46 46 46 46 46 46
19-> 54 54 54 54 54 54
20-> 64 64 64 64 64 64
21-> 76 76 76 76 76 76
22-> 89 89 89 89 89 89
23-> 104 104 104 104 104 104
24-> 122 122 122 122 122 122
25-> 142 142 142 142 142 142
26-> 165 165 165 165 165 165
27-> 192 192 192 192 192 192
28-> 222 222 222 222 222 222
29-> 256 256 256 256 256 256
30-> 296 296 296 296 296 296
31-> 340 340 340 340 340 340
32-> 390 390 390 390 390 390
33-> 448 448 448 448 448 448
34-> 512 512 512 512 512 512
35-> 585 585 585 585 585 585
36-> 668 668 668 668 668 668
37-> 760 760 760 760 760 760
38-> 864 864 864 864 864 864
39-> 982 982 982 982 982 982
40-> 1113 1113 1113 1113 1113 1113
41-> 1260 1260 1260 1260 1260 1260
42-> 1426 1426 1426 1426 1426 1426
43-> 1610 1610 1610 1610 1610 1610
44-> 1816 1816 1816 1816 1816 1816
45-> 2048 2048 2048 2048 2048 2048
46-> 2304 2304 2304 2304 2304 2304
47-> 2590 2590 2590 2590 2590 2590
48-> 2910 2910 2910 2910 2910 2910
49-> 3264 3264 3264 3264 3264 3264
50-> 3658 3658 3658 3658 3658 3658
51-> 4097 4097 4097 4097 4097 4097
52-> 4582 4582 4582 4582 4582 4582
53-> 5120 5120 5120 5120 5120 5120
54-> 5718 5718 5718 5718 5718 5718
55-> 6378 6378 6378 6378 6378 6378
56-> 7108 7108 7108 7108 7108 7108
57-> 7917 7917 7917 7917 7917 7917
58-> 8808 8808 8808 8808 8808 8808
59-> 9792 9792 9792 9792 9792 9792
60-> 10880 10880 10880 10880 10880 10880
61-> 12076 12076 12076 12076 12076 12076
62-> 13394 13394 13394 13394 13394 13394
63-> 14848 14848 14848 14848 14848 14848
64-> 16444 16444 16444 16444 16444 16444
65-> 18200 18200 18200 18200 18200 18200
66-> 20132 20132 20132 20132 20132 20132
67-> 22250 22250 22250 22250 22250 22250
68-> 24576 24576 24576 24576 24576 24576
69-> 27130 27130 27130 27130 27130 27130
70-> 29927 29927 29927 29927 29927 29927
71-> 32992 32992 32992 32992 32992 32992
72-> 36352 36352 36352 36352 36352 36352
73-> 40026 40026 40026 40026 40026 40026
74-> 44046 44046 44046 44046 44046 44046
75-> 48446 48446 48446 48446 48446 48446
76-> 53250 53250 53250 53250 53250 53250
77-> 58499 58499 58499 58499 58499 58499
78-> 64234 64234 64234 64234 64234 64234
79-> 70488 70488 70488 70488 70488 70488
80-> 77312 77312 77312 77312 77312 77312
81-> 84756 84756 84756 84756 84756 84756
82-> 92864 92864 92864 92864 92864 92864
83-> 101698 101698 101698 101698 101698 101698
84-> 111322 111322 111322 111322 111322 111322
85-> 121792 121792 121792 121792 121792 121792
86-> 133184 133184 133184 133184 133184 133184
87-> 145578 145578 145578 145578 145578 145578
88-> 159046 159046 159046 159046 159046 159046
89-> 173682 173682 173682 173682 173682 173682
90-> 189586 189586 189586 189586 189586 189586
91-> 206848 206848 206848 206848 206848 206848
92-> 225585 225585 225585 225585 225585 225585
93-> 245920 245920 245920 245920 245920 245920
94-> 267968 267968 267968 267968 267968 267968
95-> 291874 291874 291874 291874 291874 291874
96-> 317788 317788 317788 317788 317788 317788
97-> 345856 345856 345856 345856 345856 345856
98-> 376256 376256 376256 376256 376256 376256
99-> 409174 409174 409174 409174 409174 409174
100-> 444793 444793 444793 444793 444793 444793