3007. Maximum Number That Sum of the Prices Is Less Than or Equal to K

3007. Maximum Number That Sum of the Prices Is Less Than or Equal to K

Description

You are given an integer k and an integer x. The price of a numbernum is calculated by the count of set bits at positions x, 2x, 3x, etc., in its binary representation, starting from the least significant bit. The following table contains examples of how price is calculated.

xnumBinary RepresentationPrice
113000001101 3
2130000011011
22330111010013
3130000011011
33621011010102

The accumulated price ofnumis the total price of numbers from 1 to num. num is considered cheap if its accumulated price is less than or equal to k.

Return the greatest cheap number.

Example 1:

Input: k = 9, x = 1

Output: 6

Explanation:

As shown in the table below, 6 is the greatest cheap number.

xnumBinary RepresentationPriceAccumulated Price
1100111
1201012
1301124
1410015
1510127
1611029
17111312

Example 2:

Input: k = 7, x = 2

Output: 9

Explanation:

As shown in the table below, 9 is the greatest cheap number.

xnumBinary RepresentationPriceAccumulated Price
21000100
22001011
23001112
24010002
25010102
26011013
27011114
28100015
29100116
210101028

Constraints:

  • 1 <= k <= 10^15
  • 1 <= x <= 8

Hints/Notes

Solution

Language: C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Solution {
public:
long long num;
int x, n;
vector<vector<long long>> dp;

long long findMaximumNumber(long long k, int x) {
this->x = x;
// there is one elgible number every 2^x numbers
long long left = 0, right = (k + 1) << x;
while (left + 1 < right) {
long long mid = left + (right - left) / 2;
if (f(mid) > k) {
right = mid;
} else {
left = mid;
}
}
return left;
}

long long f(long long num) {
this->num = num;
n = __lg(num);
dp.resize(n + 1, vector<long long>(n + 1, -1));
long long res = dfs(n, 0, true);
return res;
}

long long dfs(int index, int price, int limit_high) {
if (index == -1) {
return price;
}
if (!limit_high && dp[index][price] != -1) {
return dp[index][price];
}
int hi = limit_high ? (num >> index) & 1 : 1;
long long res = 0;
for (int i = 0; i <= hi; i++) {
int tmp = 0;
if ((index + 1) % x == 0) {
tmp = i;
}
res += dfs(index - 1, price + tmp, limit_high && i == hi);
}
if (!limit_high) {
dp[index][price] = res;
}
return res;
}
};