summaryrefslogtreecommitdiffstats
path: root/01-algorithmic_toolbox/04-dynamic_programming/01-primitive_calculator
diff options
context:
space:
mode:
Diffstat (limited to '01-algorithmic_toolbox/04-dynamic_programming/01-primitive_calculator')
-rw-r--r--01-algorithmic_toolbox/04-dynamic_programming/01-primitive_calculator/primitive_calculator.cpp130
1 files changed, 115 insertions, 15 deletions
diff --git a/01-algorithmic_toolbox/04-dynamic_programming/01-primitive_calculator/primitive_calculator.cpp b/01-algorithmic_toolbox/04-dynamic_programming/01-primitive_calculator/primitive_calculator.cpp
index 0131b53..4ce529b 100644
--- a/01-algorithmic_toolbox/04-dynamic_programming/01-primitive_calculator/primitive_calculator.cpp
+++ b/01-algorithmic_toolbox/04-dynamic_programming/01-primitive_calculator/primitive_calculator.cpp
@@ -4,28 +4,128 @@
using std::vector;
-vector<int> optimal_sequence(int n) {
- std::vector<int> sequence;
- while (n >= 1) {
- sequence.push_back(n);
- if (n % 3 == 0) {
- n /= 3;
- } else if (n % 2 == 0) {
- n /= 2;
- } else {
- n = n - 1;
+// How to express C(n) through C(n/3), C(n/2), C(n − 1):q
+
+vector<int> optimal_sequence(int n)
+{
+ std::vector<int> sequence;
+ while (n >= 1) {
+ sequence.push_back(n);
+ if (n % 3 == 0) {
+ n /= 3;
+ } else if (n % 2 == 0) {
+ n /= 2;
+ } else {
+ n = n - 1;
+ }
}
- }
- reverse(sequence.begin(), sequence.end());
- return sequence;
+ reverse(sequence.begin(), sequence.end());
+ return sequence;
+}
+
+#define NAN std::numeric_limits<int>::max()
+
+static inline int best(int a, int b, int c)
+{
+ int r = std::numeric_limits<int>::max();
+
+ if (c != 0 && c < r)
+ r = c;
+ if (b != 0 && b < r)
+ r = b;
+ /* if (a != 0 && a < r) */
+ if (a < r)
+ r = a;
+
+ return r;
+}
+
+static inline int which(int a, int b, int c)
+{
+ int i = -1;
+ int r = std::numeric_limits<int>::max();
+
+ if (c != 0 && c < r) {
+ r = c;
+ i = 2;
+ }
+ if (b != 0 && b < r) {
+ r = b;
+ i = 1;
+ }
+ /* if (a != 0 && a < r) */
+ if (a < r)
+ i = 0;
+
+ return i;
+}
+
+vector<int> jzu(int n)
+{
+ vector<int> solution;
+
+ int N = n + 1;
+ int *add1 = new int[N];
+ int *mult2 = new int[N];
+ int *mult3 = new int[N];
+
+ add1[2] = mult2[2] = mult3[3] = 1;
+ add1[3] = 2;
+ /* std::cout << "0| " << add1[0] << " " << mult2[0] << " " << mult3[0] << std::endl; */
+ /* std::cout << "1| " << add1[1] << " " << mult2[1] << " " << mult3[1] << std::endl; */
+ /* std::cout << "2| " << add1[2] << " " << mult2[2] << " " << mult3[2] << std::endl; */
+ /* std::cout << "3| " << add1[3] << " " << mult2[3] << " " << mult3[3] << std::endl; */
+
+ int c3 = 0;
+ bool even = true;
+ for (size_t i = 4, j = 3; i < N ; i++, j++) {
+
+ add1[i] = best(add1[j], mult2[j], mult3[j]) + 1;
+
+ if (even) {
+ int k = i >> 1;
+ mult2[i] = best(add1[k], mult2[k], mult3[k]) + 1;
+ }
+
+ if (c3 == 2) {
+ int k = i / 3;
+ mult3[i] = best(add1[k], mult2[k], mult3[k]) + 1;
+ c3 = 0;
+ } else
+ c3++;
+
+ even = !even;
+ /* std::cout << i << "| " << add1[i] << " " << mult2[i] << " " << mult3[i] << std::endl; */
+ }
+
+ while (n > 1) {
+ solution.push_back(n);
+ int op = which(add1[n], mult2[n], mult3[n]);
+ if (op == 0) {
+ n--;
+ } else if (op == 1) {
+ n /= 2;
+ } else
+ n /= 3;
+ }
+ solution.push_back(1);
+
+ delete [] add1;
+ delete [] mult2;
+ delete [] mult3;
+
+ return solution;
}
int main() {
int n;
std::cin >> n;
- vector<int> sequence = optimal_sequence(n);
+ /* vector<int> sequence = optimal_sequence(n); */
+ vector<int> sequence = jzu(n);
std::cout << sequence.size() - 1 << std::endl;
- for (size_t i = 0; i < sequence.size(); ++i) {
+ for (size_t i = sequence.size() - 1; i > 0; i--) {
std::cout << sequence[i] << " ";
}
+ std::cout << sequence[0] << " ";
+ std::cout << '\n';
}