First, we need to come up with a recursive formula:
Starting from the least significant digit (LSD) to the most significant digit (MSD), we have the right solution if, after calculating the MSD, we have S(x) = S(x*m)
To check if a number is a valid solution, we need to know three things:
- What is the current sum of the digit S (x)
- What is the current sum of the digit S (x * m)
- What is the current number.
So, to answer the first and last, itβs easy, we just need to support two parameters sum and digit . To calculate the second, we need to save two additional parameters: sumOfProduct and lastRemaining .
sumOfProduct - current S (x * m)lastRemaining is the result (m * current digit value + lastRemaining) / 10
For example, we have x = 123 and m = 23
First digit = 3
sum = 3 digit = 0 sumOfProduct += (lastRemaining + 3*m) % 10 = 9 lastRemaining = (m*3 + 0)/10 = 6
Second digit = 2
sum = 5 digit = 1 sumOfProduct += (lastRemaining + 2*m) % 10 = 11 lastRemaining = (m*2 + lastRemaining)/10 = 5
Last digit = 1
sum = 6 digit = 2 sumOfProduct += (lastRemaining + m) % 10 = 19 lastRemaining = (m + lastRemaining)/10 = 2
Since this is the last digit, sumOfProduct += S(lastRemaining) = 21 .
So x = 123 and m = 23 are not a valid number. Check x*m = 2829 -> S(x*m) = S(2829) = 21 .
So, we can have a recursive formula with state (digit, sum, sumOfProdut, lastRemaining) .
Thus, our dynamic programming state is dp[18][18*9 + 1][18*9 + 1][200] (as m <= 100, so lastRemaining not more than 200).
Now the dp state exceeds 300 MB, but if we use an iterative approach, it will become smaller using about 30 MB
source share