# Count numbers (smaller than or equal to N) with given digit sum

Given a number N and a sum S, find the count of numbers upto N that have digit sum equal to S.

```Examples:
Input : N = 100, S = 4
Output : 5
Upto 100 only 5 numbers(4, 13, 22, 31, 40)
can produce 4 as their sum of digits.

Input : N = 1000, S = 1
Output : 4
Upto 1000 only 4 numbers(1, 10, 100 and 1000)
can produce 1 as their sum of digits.
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

We can do a digit DP having state (current index, whether the currently constructed number of i digits is equal or less than the number formed by first i digits of N, the sum of digits of currently constructed number).

Let dp[i][tight][sum_so_far] denotes the count of numbers whose first i digits have been considered and tight denotes whether the currently constructed number is equal or less than number formed by first i digits of N. If tight is true, then it means that currently constructed number is equal to the number constructed by first i digits of N. If it is false then it means that currently constructed number is less than the number constructed by first i digits of N. sum_so_far denotes the sum of digits of currently constructed number.

Base Case:
If i = number of digits in N, sum_so_far = Sum, then answer = 1 else answer is 0.

Transitions:
For filling (i+1)th digit we can consider following –
If tight is true, then it means that our constructed number is still equal to number formed by first i digits of N. We can try our current possible digit value from 0 to (i+1)th digit of N. If we try the digit more than (i+1)th digit, then the constructed number will become greater than number formed by first i digits of N, which will violate the property that our constructed number should be <= N.
If tight is false, then it means that number constructed from first i – 1 digits has become less than number constructed from the first i – 1 digit of N, So it means that our number can never exceed N, so we can chose the any digit from 0 to 9.
nsum_so_far can be obtained by adding sum_so_far and current digit(currdigit).

Finally we will return answer which is count of numbers upto N that have digit sum equal to S.

## C++

 `#include ` `using` `namespace` `std; ` ` `  `// N can be max 10^18 and hence digitsum will be 162 maximum. ` `long` `long` `dp; ` ` `  `long` `long` `solve(``int` `i, ``bool` `tight, ``int` `sum_so_far, ` `                ``int` `Sum, string number, ``int` `len) ` `{ ` `    ``if` `(i == len) { ` ` `  `        ``// If sum_so_far equals to given sum then  ` `        ``// return 1 else 0 ` `        ``if` `(sum_so_far == Sum) ` `            ``return` `1; ` `        ``else` `            ``return` `0; ` `    ``} ` ` `  `    ``long` `long``& ans = dp[i][tight][sum_so_far]; ` `    ``if` `(ans != -1) { ` `        ``return` `ans; ` `    ``} ` ` `  `    ``ans = 0; ` `    ``bool` `ntight; ` `    ``int` `nsum_so_far; ` `    ``for` `(``char` `currdigit = ``'0'``; currdigit <= ``'9'``; currdigit++) { ` ` `  `        ``// Our constructed number should not become ` `        ``// greater than N. ` `        ``if` `(!tight && currdigit > number[i]) { ` `            ``break``; ` `        ``} ` ` `  `        ``// If tight is true then it will also be true for (i+1) digit. ` `        ``ntight = tight || currdigit < number[i]; ` `        ``nsum_so_far = sum_so_far + (currdigit - ``'0'``); ` `        ``ans += solve(i + 1, ntight, nsum_so_far, Sum, number, len); ` `    ``} ` ` `  `    ``return` `ans; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``long` `long` `count = 0; ` `    ``long` `long` `sum = 4; ` `    ``string number = ``"100"``; ` `    ``memset``(dp, -1, ``sizeof` `dp); ` `    ``cout << solve(0, 0, 0, sum, number, number.size()); ` `    ``return` `0; ` `} `

## Java

 `// Java program to count 2s from 0 to n  ` `class` `GFG  ` `{ ` ` `  `// N can be max 10^18 and hence  ` `// digitsum will be 162 maximum.  ` `static` `long` `dp[][][] = ``new` `long``[``18``][``2``][``162``];  ` ` `  `static` `long` `solve(``int` `i, ``boolean` `tight, ``int` `sum_so_far,  ` `                ``int` `Sum, String number, ``int` `len)  ` `{  ` `    ``if` `(i == len)  ` `    ``{  ` ` `  `        ``// If sum_so_far equals to given sum then  ` `        ``// return 1 else 0  ` `        ``if` `(sum_so_far == Sum)  ` `            ``return` `1``;  ` `        ``else` `            ``return` `0``;  ` `    ``}  ` ` `  `    ``long` `ans = dp[i][``1``][sum_so_far];  ` `    ``if` `(ans != -``1``)  ` `    ``{  ` `        ``return` `ans;  ` `    ``}  ` ` `  `    ``ans = ``0``;  ` `    ``boolean` `ntight;  ` `    ``int` `nsum_so_far;  ` `    ``for` `(``char` `currdigit = ``'0'``; currdigit <= ``'9'``; currdigit++)  ` `    ``{  ` ` `  `        ``// Our constructed number should not become  ` `        ``// greater than N.  ` `        ``if` `(!tight && currdigit > number.charAt(i)) ` `        ``{  ` `            ``break``;  ` `        ``}  ` ` `  `        ``// If tight is true then it will  ` `        ``// also be true for (i+1) digit.  ` `        ``ntight = tight || currdigit < number.charAt(i);  ` `        ``nsum_so_far = sum_so_far + (currdigit - ``'0'``);  ` `        ``ans += solve(i + ``1``, ntight, nsum_so_far,  ` `                        ``Sum, number, len);  ` `    ``}  ` `    ``return` `ans;  ` `}  ` ` `  `// Driver code  ` `public` `static` `void` `main(String[] args)  ` `{ ` `    ``long` `count = ``0``;  ` `    ``int` `sum = ``4``;  ` `    ``String number = ``"100"``;  ` `    ``for``(``int` `i = ``0``; i < ``18``; i++) ` `    ``{ ` `        ``for``(``int` `j = ``0``; j < ``2``; j++) ` `        ``{ ` `            ``for``(``int` `k = ``0``; k < ``162``; k++) ` `            ``dp[i][j][k] = -``1``; ` `        ``} ` `    ``} ` `    ``System.out.println( solve(``0``, ``false``, ``0``, sum,  ` `                        ``number, number.length()));  ` `    ``} ` `}  ` ` `  `// This code is contributed by PrinciRaj1992 `

## Python3

 `# Python3 implementation of the given approach.  ` ` `  `def` `solve(i, tight, sum_so_far, ``Sum``, number, length):  ` ` `  `    ``if` `i ``=``=` `length:  ` ` `  `        ``# If sum_so_far equals to given  ` `        ``# sum then return 1 else 0  ` `        ``if` `sum_so_far ``=``=` `Sum``:  ` `            ``return` `1` `        ``else``: ` `            ``return` `0` `     `  `    ``ans ``=` `dp[i][tight][sum_so_far]  ` `    ``if` `ans !``=` `-``1``:  ` `        ``return` `ans  ` `     `  `    ``ans ``=` `0` `    ``for` `currdigit ``in` `range``(``0``, ``10``):  ` ` `  `        ``currdigitstr ``=` `str``(currdigit) ` `         `  `        ``# Our constructed number should  ` `        ``# not become greater than N.  ` `        ``if` `not` `tight ``and` `currdigitstr > number[i]:  ` `            ``break` ` `  `        ``# If tight is true then it will also be true for (i+1) digit.  ` `        ``ntight ``=` `tight ``or` `currdigitstr < number[i]  ` `        ``nsum_so_far ``=` `sum_so_far ``+` `currdigit  ` `        ``ans ``+``=` `solve(i ``+` `1``, ntight, nsum_so_far, ``Sum``, number, length)  ` `     `  `    ``return` `ans  ` ` `  `# Driver code  ` `if` `__name__ ``=``=` `"__main__"``: ` ` `  `    ``count, ``Sum` `=` `0``, ``4` `    ``number ``=` `"100"` `    ``dp ``=` `[[[``-``1` `for` `i ``in` `range``(``162``)] ``for` `j ``in` `range``(``2``)] ``for` `k ``in` `range``(``18``)] ` `    ``print``(solve(``0``, ``0``, ``0``, ``Sum``, number, ``len``(number))) ` ` `  `# This code is contributed by Rituraj Jain `

## C#

 `// C# program to count 2s from 0 to n  ` `using` `System; ` ` `  `class` `GFG  ` `{  ` ` `  `    ``// N can be max 10^18 and hence  ` `    ``// digitsum will be 162 maximum.  ` `    ``static` `long` `[ , , ]dp = ``new` `long``[18,2,162];  ` ` `  `    ``static` `long` `solve(``int` `i, ``bool` `tight, ``int` `sum_so_far,  ` `                    ``int` `Sum, String number, ``int` `len)  ` `    ``{  ` `        ``if` `(i == len)  ` `        ``{  ` ` `  `            ``// If sum_so_far equals to given sum then  ` `            ``// return 1 else 0  ` `            ``if` `(sum_so_far == Sum)  ` `                ``return` `1;  ` `            ``else` `                ``return` `0;  ` `        ``}  ` ` `  `        ``long` `ans = dp[i,1,sum_so_far];  ` `        ``if` `(ans != -1)  ` `        ``{  ` `            ``return` `ans;  ` `        ``}  ` ` `  `        ``ans = 0;  ` `        ``bool` `ntight;  ` `        ``int` `nsum_so_far;  ` `        ``for` `(``char` `currdigit = ``'0'``; currdigit <= ``'9'``; currdigit++)  ` `        ``{  ` ` `  `            ``// Our constructed number should not become  ` `            ``// greater than N.  ` `            ``if` `(!tight && currdigit > number[i])  ` `            ``{  ` `                ``break``;  ` `            ``}  ` ` `  `            ``// If tight is true then it will  ` `            ``// also be true for (i+1) digit.  ` `            ``ntight = tight || currdigit < number[i];  ` `            ``nsum_so_far = sum_so_far + (currdigit - ``'0'``);  ` `            ``ans += solve(i + 1, ntight, nsum_so_far,  ` `                            ``Sum, number, len);  ` `        ``}  ` `        ``return` `ans;  ` `    ``}  ` ` `  `    ``// Driver code  ` `    ``public` `static` `void` `Main(String[] args)  ` `    ``{  ` `        ``int` `sum = 4;  ` `        ``String number = ``"100"``;  ` `        ``for``(``int` `i = 0; i < 18; i++)  ` `        ``{  ` `            ``for``(``int` `j = 0; j < 2; j++)  ` `            ``{  ` `                ``for``(``int` `k = 0; k < 162; k++)  ` `                ``dp[i,j,k] = -1;  ` `            ``}  ` `        ``}  ` `        ``Console.WriteLine( solve(0, ``false``, 0, sum,  ` `                            ``number, number.Length));  ` `        ``}  ` `}  ` ` `  `// This code has been contributed by Rajput-Ji `

Output:

```5
```

Time Complexity: 2(tight) * Sum * log 10(N) * 10(transitions) = 20*log 10(N)*Sum.

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

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.