Problem:
Score : 500 points

Problem Statement

Find the number of integers between 1 and N (inclusive) that contains exactly K non-zero digits when written in base ten.

Constraints

1 \leq N < 10^{100}

1 \leq K \leq 3

Input

Input is given from Standard Input in the following format:

N
K

Output

Print the count.

Sample Input 1

100
1

Sample Output 1

19

The following 19 integers satisfy the condition:

1,2,3,4,5,6,7,8,9,10,20,30,40,50,60,70,80,90,100

Sample Input 2

25
2

Sample Output 2

14

The following 14 integers satisfy the condition:

11,12,13,14,15,16,17,18,19,21,22,23,24,25

Sample Input 3

314159
2

Sample Output 3

937

Sample Input 4

9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
3

Sample Output 4

117879300

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)


import java.util.*;
import java.util.function.Consumer;

class Node {
    int pattern;
    int notZero;
    boolean max;

    Node apply(Consumer<Node> lambda) {
        lambda.accept(this);
        return this;
    }
}

class Main {
    public static void main(String args[]) {
        Scanner s = new Scanner(System.in);
        String n = s.next();
        int k = s.nextInt();

        int length = n.length();


        int[][] dp0 = {};
        int[][] dp1 = {};

        List<Node> state = Collections.emptyList();
        for (int i = 0; i < length; i++) {
            final int digit = n.charAt(i) - '0';
            if (i == 0) {
                state = new ArrayList<>();
                // 最大値君
                state.add(new Node().apply(self -> {
                    self.max = true;
                    self.notZero = 1;
                    self.pattern = 1;
                }));
                // 真中らぁら
                if(digit>1) {
                    state.add(new Node().apply(self -> {
                        self.max = false;
                        self.notZero = 1;
                        self.pattern = digit - 1;
                    }));
                }
                // わがなはぜろ
                state.add(new Node().apply(self -> {
                    self.max = false;
                    self.notZero = 0;
                    self.pattern = 1;
                }));

            } else {
                List<Node> next = new ArrayList<>();
                int[] tmp=new int[1000];
                for (Node node : state) {
                    if (node.max) {
                        // up
                        next.add(new Node().apply(self -> {
                            self.max = true;
                            self.pattern = node.pattern;
                            self.notZero = node.notZero+((digit==0)?0:1);
                        }));
                        // まなか
                        if(digit>1){
                            tmp[node.notZero+1]+=(node.pattern * (digit - 1));
                        }
                        if(digit>0){
                            //zero
                            tmp[node.notZero]+=(node.pattern );

                        }
                    } else {
                        //1-9
                        tmp[node.notZero+1]+=(node.pattern * 9);
                        // 0
                        tmp[node.notZero]+=(node.pattern );
                    }
                }
                for (int j = 0; j <tmp.length ; j++) {
                    final int jj=j;
                    if(tmp[j]<1)continue;
                    next.add(new Node().apply(self -> {
                        self.max = false;
                        self.pattern = tmp[jj];
                        self.notZero = jj;
                    }));
                }
                state = next;
            }
        }
        int ans= state.stream().filter(self -> self.notZero == k).map(self -> self.pattern).reduce(0, (p, q) -> p + q);
        System.out.println(ans);

    }
}