I am trying to solve the following problem:
Find the smallest n-bit integer c that has k 1-bits and is the sum of two n-bit integers that have g, h bits set to 1. g, h, k <= n
To begin with, an n-bit integer means that we can use all bits of n , i.e. Max. the value of such an integer is 2^n - 1 . The described integer may not be present at all. Obviously, the case k > g + h has no solutions, and for g + h = k answer is simply 2^k - 1 (the first k bits are 1 bit, k - n zeros in front).
As for some examples of what the program should do:
g = h = k = 4, n = 10 : 0000001111 + 0000001111 = 0000011110 15 + 15 = 30 (30 should be the output) (4, 6, 5, 10): 0000011110 + 0000111111 = 0001011101 30 + 63 = 93 (30, 1, 1, 31): 1 + (2^30 - 1) = 2^30
As I think of it, this is a dynamic programming problem, and I chose the following approach: Let dp[g][h][k][n][c] be the described integer, and c optional bit for transfer. I am trying to recover possible amounts depending on the least significant bit. So dp[g][h][k][n + 1][0] is the minimum
(0, 0): dp[g][h][k][n][0] (0, 0): 2^n + dp[g][h][k - 1][n][1] (1, 0): 2^n + dp[g - 1][h][k - 1][n][0] (0, 1): 2^n + dp[g][h - 1][k - 1][n][0]
Similarly, dp[g][h][k][n + 1][1] is the minimum
(1, 1): dp[g - 1][h - 1][k][n][0] (1, 1): dp[g - 1][h - 1][k - 1][n][1] + 2^n (1, 0): dp[g - 1][h][k][n][1] (0, 1): dp[g][h - 1][k][n][1]
The idea is not so difficult, but I do not really understand such things, and my algorithm does not work even in the simplest cases. I chose the approach from top to bottom. Itβs hard for me to consider all angular cases. I really don't know if I chose the recursion base correctly, etc. My algorithm does not even work for the simplest case for g = h = k = 1, n = 2 (answer 01 + 01 = 10 ). The answer to g = h = k = 1, n = 1 should not be the answer, but the algorithm gives 1 (which is basically why in the first example 1 is displayed instead of 2 ). So here is my awful code (only very simple C ++):
int solve(int g, int h, int k, int n, int c = 0) { if (n <= 0) { return 0; } if (dp[g][h][k][n][c]) { return dp[g][h][k][n][c]; } if (!c) { if (g + h == k) { return dp[g][h][k][n][c] = (1 << k) - 1; } int min, a1, a2, a3, a4; min = a1 = a2 = a3 = a4 = std::numeric_limits<int>::max(); if (g + h > k && k <= n - 1) { a1 = solve(g, h, k, n - 1, 0); } if (g + h >= k - 1 && k - 1 <= n - 1) { a2 = (1 << (n - 1)) + solve(g, h, k - 1, n - 1, 1); } if (g - 1 + h >= k - 1 && k - 1 <= n - 1) { a3 = (1 << (n - 1)) + solve(g - 1, h, k - 1, n - 1, 0); } if (g + h - 1 >= k - 1 && k - 1 <= n - 1) { a4 = (1 << (n - 1)) + solve(g, h - 1, k - 1, n - 1, 0); } min = std::min({a1, a2, a3, a4}); return dp[g][h][k][n][c] = min; } else { int min, a1, a2, a3, a4; min = a1 = a2 = a3 = a4 = std::numeric_limits<int>::max(); if (g - 2 + h >= k && k <= n - 1) { a1 = solve(g - 1, h - 1, k, n - 1, 0); } if (g - 2 + h >= k - 1 && k - 1 <= n - 1) { a2 = (1 << (n - 1)) + solve(g - 1, h - 1, k - 1, n - 1, 1); } if (g - 1 + h >= k && k <= n - 1) { a3 = solve(g - 1, h, k, n - 1, 1); } if (g - 1 + h >= k && k <= n - 1) { a4 = solve(g, h - 1, k, n - 1, 1); } min = std::min({a1, a2, a3, a4}); return dp[g][h][k][n][c] = min; } }