Decompose an Integer in sum of integers containing only 1,2,3 as its digit - dynamic-programming

I was struggling with a problem on Atcoder, in which we have to find minimum K for a number N such that K numbers of whose digits are either 1, 2, or 3 can sum up to N.
Through editorial, I could only understand, if
p is good if p = 10a + b
where a is either 0 or a is itself that kind of number and b is either 1, 2, or 3.
from this point onward, I'm not able under how to proceed further and what the author is meant by a good number. This problem seems really delicate but its solution is bizarre. Also, give me a better solution if possible.
problem link: https://atcoder.jp/contests/arc123/tasks/arc123_c

Related

Unique numbers with missing digits

I have this problem that I must solve in time that is polynomial in N, K and D given below:
Let N, K be some natural numbers.
Then a, b, c ... are N numbers of exactly K digits each.
a, b, c ... contain only the digits 1 and 2 in some order given by the input.
Although, there have only D digits that are visible, the rest of them being hidden (the hidden digits will be noted with the character "?").
There may be different numbers such that one or more of a, b, c ... are generalizations of the said number:
e.g.
2?122 is a generalization for 21122 and 22122
2?122 is not a generalization for 11111
12??? and ?21?? are both generalizations for 12112
???22 and ???11 cannot be generalizations of the same number
Basically, some number is a generalization of the other if the latter can be one of the "unhidden" versions of the former.
Question:
How many different numbers there are such that at least one of a, b, c or ... is their generalization?***
Quick Reminder:
N = nº of numbers
K = nº of digits in each number
D = nº of visible digits in each number
Conditions & Limitations:
N, K, D are natural numbers
1 ≤ N
1 ≤ D < K
Input / Output snippets for verification of the algorithm:
Input:
N = 3, K = 5, D = 3
112??
?122?
1?2?1
Output:
8
Explanation:
The numbers are 11211, 11212, 11221, 11222, 12211, 12221, 21221, 21222, which are 8 numbers.
11211, 11212, 11221, 11222 are the generalizations of 112??
11221, 11222, 21221, 21222 are the generalizations of ?122?
11211, 11221, 12211, 12221 are the generalizations of 1?2?1
Input:
N = 2, K = 3, D = 1
1??
?2?
Output:
6
Explanation:
The numbers are 111, 112, 121, 122, 221, 222, which are 6 numbers.
From my calculations, I found out that there are 2^(K-D) possible numbers in total that have a as their generalization, 2^(K-D) possible numbers in total that have b as their generalization etc., leaving me with N*2^(K-D) numbers.
My big problem is that I found cases where a number has multiple generalizations and therefore it repeats inside N*2^(K-D), so the real nº of different numbers will be, in this case, something smaller than N*2^(K-D).
I don't know how to find only the different numbers and I need your help.
Thank you very much!
EDIT: Answer to «n. 1.8e9-where's-my-share m.»'s question from the comments:
If you have two generalisations, can you find out how many numbers they both generalise?
For two given general numbers a and b (general meaning that they both contain "?"), it is possible to find nº of numbers generalised by both a and b in polynomial time by using the following logic:
1 - we declare some variable q = 1
2 - we start "scanning" the digits of the two numbers simultaneously from left to right:
2.1 - if we find two unhidden digits and they are different, then no numbers are generalized by both a and b and we return 0
2.2 - if we find two hidden digits, then we multiply q by 2, since of the two general numbers result to both generalize some number, that number can have 1 or 2 in place of "?", therefore for each "?" we double the numbers that can be generalized from both a and b as long as step 2.1 is never true.
3 - if scanned all the digits and step 2.1 was never true, then we return 2^q
Therefore, the nº of numbers both a and b generalize is 0 or 2^q, according to the cases presented above.
Unfortunately, this is impossible to do in polynomial time (unless P=NP, and maybe not even then.) Your problem is equivalent to the problem of counting satisfying assignments to a formula in Disjunctive Normal Form, called the DNF counting problem. DNF counting is Sharp-P-hard, so a polynomial time solution could be used to solve all problems in NP in polynomial time too (and more).
To see the relationship, note that each pattern is equivalent to an AND of several literals. If you take '1' in a position to be a literal, and '2' in that position to be that literal negated, you can convert it to a disjunctive clause.
For example:
1 1 2 ? ?
becomes
(x_1 ∧ x_2 ∧ ¬x_3)
? 1 2 2 ?
becomes
(x_2 ∧ ¬x_3 ∧ ¬x_4)
1 ? 2 ? 1
becomes
(x_1 ∧ ¬x_3 ∧ x_5)
The question of how many numbers satisfy at least one of these patterns is exactly the question of how many assignments satisfy at least one of the equivalent clauses.

how to find all numbers that there distance from given point are less or equall to integer n

given a set of points D and some number K I want to find all numbers that are in D such that the distance between K and any found number is less or equal to integer N?
Example:
suppose we have D={5,9,0,6,7} and K=8 and N=1 then the result should be {9,7}
I was thinking to use k-d tree or VP tree but both as I understand (correct me if I am wrong please) find nearest neighbors and do not care about N in my example.
To summarize all the comment:
Solve this problem as brute force will take O(n) time as iterate on each element in D and check if its distance from k is less then n.
You have big data set but a lot of queries it is better to do pre-processing on D (with O(nlogn) and the you can get the answer in O(logn) -> by sorting D as pre-processes (in O(nlogn) as dimple sort of array.
Now, on given query search for k - notice binary search will stop if the number missing but he do stop at the closest value. From that index start spread to both side of D and for each check if still in n range. Notice the spreading in allow as it is include of O(|output|).
In your example: sorted D yield: [0,5,6,7,9]. Try finding k=8 will give false but index 3 or 4 (depended on the implementation). Let say is return index 3. for 3 till last index check if arr[i] - k < n if so print - if bigger stop. For the other side check k - arr[i] < n - if so print and if bigger stop -> this will give you 7,9
Hope that helps!

Delete as few as possible digits to make number divisible by 3

I was solving this question, namely we have given number N, which can be very big, it can have up to 100000 digits.
Now I want to know what is the most efficient way to find those digits, and I think that in big numbers I will need to delete at most 3 digits to make the number divisible by 3.
I know that number is divisible by three if the sum of its digits is divisible by three, but I can't think of how can we use this.
My idea is to brute force over the string and to check if we delete that digit is the number going to be divisible by 3, but my solution fails at complex examples. Please give me some hints.
Thanks in advance.
If the sum of the digits modulo 3 is equal to 1, you want to delete a single 1, 4, or 7. If the sum of the digits is 2, you want to delete a single 2, 5, or 8.
If that can't be done, then you have to delete two digits.
To avoid scanning the list twice, you could remember the indices of up to two digits congruent to 1, and the indices of up to two digits congruent to 2, so when you compute the final modulus you know where to look.
The number 3 has some special properties relative to a base-10 number system that you can leverage.
10 is 1 more than 9, and 9 is evenly divisible by 3, so the "1" in "10" acts as a sort of remainder from adding 1 to 9. As a result, if the sum of all digits in the number is evenly divisible by 3 then that number is also divisible by 3.
So if you begin by figuring out what the modulo is after adding all the digits, then you'll know whether the number is divisible by zero (i.e. results in a modulo zero) or not. If not, then you can subtract one digit at a time, recalculating the modulo of the resulting number until you end up with a modulo of zero.
You should check what makes a number divisible by 3. If you find it you should divide the problem into smaller problems

Inversions in a binary string

How many inversions are there in a binary string of length n ?
For example , n = 3
000->0
001->0
010->1
011->0
100->2
101->1
110->2
111->0
So total inversions are 6
The question looks like a homework, that's why let me omit the details. You can:
Solve the problem as a recurrency (see Толя's answer)
Make up and solve the characteristic equation, get the solution as a close formula with some arbitrary constants (c1, c2, ..., cn); as the matter of fact you'll get just one unknown constant.
Put some known solutions (e.g. f(1) = 0, f(3) = 6) into the formula and find out all the unknown coefficients
The final answer you should get is
f(n) = n*(n-1)*2**(n-3)
where ** means raising into power (2**(n-3) is 2 in n-3 power). In case you don't want to deal with recurrency and the like stuff, you can just prove the formula by induction.
It is easy recurrent function.
Assume that we know answer for n-1.
And after ato all previous sequences we add 0 or 1 as first character.
if we adding 0 as first character that mean that count of inversions will not be changed: hence answer will be same as for n-1.
if we adding 1 as first character that mean count of inversions will be same as before and will be added extra inversion equals to count of 0 into all previous sequences.
Count of zeros ans ones in sequences of length n-1 will be:
(n-1)*2^(n-1)
Half of them is zeros it will give following result
(n-1)*2^(n-2)
It means that we have following formula:
f(1) = 0
f(n) = 2*f(n-1) + (n-1)*2^(n-2)

Use dynamic programming to find a subset of numbers whose sum is closest to given number M

Given a set A of n positive integers a1, a2,... a3 and another positive integer M, I'm going to find a subset of numbers of A whose sum is closest to M. In other words, I'm trying to find a subset A′ of A such that the absolute value |M - 􀀀 Σ a∈A′| is minimized, where [ Σ a∈A′ a ] is the total sum of the numbers of A′. I only need to return the sum of the elements of the solution subset A′ without reporting the actual subset A′.
For example, if we have A as {1, 4, 7, 12} and M = 15. Then, the solution subset is A′ = {4, 12}, and thus the algorithm only needs to return 4 + 12 = 16 as the answer.
The dynamic programming algorithm for the problem should run in
O(nK) time in the worst case, where K is the sum of all numbers of A.
You construct a Dynamic Programming table of size n*K where
D[i][j] = Can you get sum j using the first i elements ?
The recursive relation you can use is: D[i][j] = D[i-1][j-a[i]] OR D[i-1][j] This relation can be derived if you consider that ith element can be added or left.
Time complexity : O(nK) where K=sum of all elements
Lastly you iterate over entire possible sum you can get, i.e. D[n][j] for j=1..K. Which ever is closest to M will be your answer.
For dynamic algorithm, we
Define the value we would work on
The set of values here is actually a table.
For this problem, we define value DP[i , j] as an indicator for whether we can obtain sum j using first i elements. (1 means yes, 0 means no)
Here 0<=i<=n, 0<=j<=K, where K is the sum of all elements in A
Define the recursive relation
DP[i+1 , j] = 1 , if ( DP[i,j] == 1 || DP[i,j-A[i+1]] ==1)
Else, DP[i+1, j] = 0.
Don't forget to initialize the table to 0 at first place. This solves boundary and trivial case.
Calculate the value you want
Through bottom-up implementation, you can finally fill the whole table.
Now, things become easy. You just need to find out the closest value to M in the table whose value is one.
Here, just work on DP[n][j], since n covers the whole set. Find the closest j to M whose value is 1.
Time complexity is O(kn), since you iterate k*n times in total.

Resources