Given an Integer N, and a number K, the task is to find out the total numbers from 0 to N which have exactly K non zero digits and the sum of those digits should be odd and that sum should be distinct. The number N can be as large as 10^18.
Examples:
Input : N = 10, K = 1
Output : 5
The numbers which follow the conditions are >
1, 3, 5, 7 and 9
The digit sum of 10 that is (1+0) = 1 is also odd, but 1 is already included in our count.Input : N = 100, K = 2
Output : 8
Prerequisites: DigitDP
Naive Approach:
A naive approach for linear traversing in O(N) of all elements from 0 to N and calculating sum of digits in log(n) where n is the number of digits in that number will fail for large inputs of N.
Efficient Approach:
 We can use Dynamic Programming and it’s very useful technique that is digitdp to solve this problem.
 So instead of keeping a record of nonzero integers, we keep a record of zeroes we can keep at different indices, idx in variable K. The number of zeroes we can keep can be found initially by subtracting K with the number of digits in N.
 We keep all the digits of N into a vector say, digits.

Now, we calculate range of elements we can keep at index idx by analysing K.
 Suppose at index idx, we are left with K = 1 (A Nonzero value), then our range to put elements is [0, j] where j is the upper bound decided by the tight value obtained from the current index of the digit from vector digits.
 If at idx, we are left with K = 0, then our range becomes [1, j] because we can’t put in 0 there.
 Now, also take a parameter that is sum, which will calculate the sum of digits of a number till the base case hits successfully.
 Also, a boolean map is used which will store all the odd sums calculated already, so it gives distinct odd sums.

The recurrence will be:
where j = digits[idx] if tight = 0, else j = 9

Base Case:

When idx = digits.size(), K == 0 and sum is odd.
We mark the sum as true and return 1 else return 0.  If idx > digits.size() then return 0.

When idx = digits.size(), K == 0 and sum is odd.
So we create a DP table say DP[idx][K][tight][sum] which will store our result from the recurrence above and return the count by memoizing it to this DP table.
Below is the implementation of the above approach:
// C++ program to Count the numbers having // exactly K nonzero digits and sum // of digits are odd and distinct. #include <bits/stdc++.h> using namespace std; // To store digits of N vector< int > digits; // visited map bool vis[170] = { false }; // DP Table int dp[19][19][2][170]; // Push all the digits of N into // digits vector void ConvertIntoDigit( int n) { while (n) { int dig = n % 10; digits.push_back(dig); n /= 10; } reverse(digits.begin(), digits.end()); } // Function returns the count int solve( int idx, int k, int tight, int sum) { // If desired number is formed // whose sum is odd if (idx == digits.size() && k == 0 && sum & 1) { // If it is not present in map, // mark it as true and return 1 if (!vis[sum]) { vis[sum] = 1; return 1; } // Sum is present in map already return 0; } // Desired result not found if (idx > digits.size()) { return 0; } // If that state is already calculated // just return that state value if (dp[idx][k][tight][sum]) { return dp[idx][k][tight][sum]; } // Upper limit int j; if (tight == 0) { j = digits[idx]; } else { j = 9; } // To store the count of // desired numbers int cnt = 0; // If k is nonzero, i ranges from // 0 to j else [1, j] for ( int i = (k ? 0 : 1); i <= j; i++) { int newtight = tight; if (i < j) { newtight = 1; } // If current digit is 0, decrement // k and recurse sum is not changed // as we are just adding 0 that // makes no difference if (i == 0) cnt += solve(idx + 1, k  1, newtight, sum); // If i is non zero, then k remains // unchanged and value is added to sum else cnt += solve(idx + 1, k, newtight, sum + i); } // Memoize and return return dp[idx][k][tight][sum] = cnt; } // Driver code int main() { // K is the number of exact nonzero // elements to have in number int N, k; N = 169, k = 2; // break N into its digits ConvertIntoDigit(N); // We keep record of 0s we need to // place in the number k = digits.size()  k; cout << solve(0, k, 0, 0); } 
12
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a studentfriendly price and become industry ready.
Recommended Posts:
 Count of Ndigit numbers with all distinct digits
 Count numbers whose maximum sum of distinct digitsum is less than or equals M
 Count numbers less than N containing digits from the given set : Digit DP
 Count numbers formed by given two digit with sum having given digits
 Count of n digit numbers whose sum of digits equals to given sum
 Count of N digit Numbers whose sum of every K consecutive digits is equal
 Count of N digit Numbers whose sum of every K consecutive digits is equal  Set 2
 Count total number of N digit numbers such that the difference between sum of even and odd digits is 1
 Count of Ndigit numbers with absolute difference of adjacent digits not exceeding K  Set 2
 Count of Ndigit numbers with absolute difference of adjacent digits not exceeding K
 Count of Numbers in Range where first digit is equal to last digit of the number
 Check if all subnumbers have distinct Digit product
 Count numbers in a range with digit sum divisible by K having first and last digit different
 Numbers having Unique (or Distinct) digits
 Count distinct pairs from two arrays having same sum of digits
 N digit numbers divisible by 5 formed from the M digits
 Print all ndigit numbers whose sum of digits equals to given sum
 Count of numbers between range having only nonzero digits whose sum of digits is N and number is divisible by M
 Count of numbers upto N digits formed using digits 0 to K1 without any adjacent 0s
 Sum of all N digit palindromic numbers divisible by 9 formed using digits 1 to 9
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.