Problem:
Balls and Boxes 3

Balls

Boxes

Any way

At most one ball

At least one ball

Distinguishable

Distinguishable

1

2

3

Indistinguishable

Distinguishable

4

5

6

Distinguishable

Indistinguishable

7

8

9

Indistinguishable

Indistinguishable

10

11

12

Problem

You have $n$ balls and $k$ boxes. You want to put these balls into the boxes.

Find the number of ways to put the balls under the following conditions:

Each ball is distinguished from the other.

Each box is distinguished from the other.

Each ball can go into only one box and no one remains outside of the boxes.

Each box must contain at least one ball.

Note that you must print this count modulo $10^9+7$.

Input

$n$ $k$

The first line will contain two integers $n$ and $k$.

Output

Print the number of ways modulo $10^9+7$ in a line.

Constraints

$1 \le n \le 1000$

$1 \le k \le 1000$

Sample Input 1

4 3

Sample Output 1

36

Sample Input 2

10 3

Sample Output 2

55980

Sample Input 3

100 100

Sample Output 3

437918130

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace CsharpSpiral {
    partial class Program {
        static void Main(string[] args) {
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(sw);
            new Program().Solve(new ConsoleInput(Console.In, ' '));
            Console.Out.Flush();
        }
        public void Solve(ConsoleInput cin) {
            var n = cin.ReadInt;
            var k = cin.ReadInt;
            const int modulo= 1000000007;
            var F = new ResidueField(modulo);
            if(n < k) Console.WriteLine(0);
            else {
                var D = new long[n + 1, k + 1];
                D[1, 1] = 1;
                for(int i = 1; i <= n; i++) {
                    D[i, 1] = 1;
                    for(int j = 2; j < i && j <= k; j++) { 
                        D[i, j] = F.Add(F.Mul(D[i - 1, j], j), D[i - 1, j - 1]);
                    }
                    if(i <= k) D[i, i] = 1;
                }
                Console.WriteLine(F.Mul(D[n, k], F.Factorial(k)));
            }
        }
        class ResidueField {
            public readonly long modulo;
            public ResidueField(long mModulo) {
                modulo = mModulo;
            }
            private long[] factorialTable = { 1 };
            private int factorialTableLastIndex { get { return factorialTable.Length - 1; } }
            public long mod(long x) => x < 0 ? x % modulo + modulo : x % modulo;
            public long Add(long a, long b) => mod(a + b);
            public long Sub(long a, long b) => mod(a - b);
            public long Mul(long a, long b) => mod(a * b);
            public long Pow(long a, long n) {
                if(n == 0) return 1;
                var R = 1L;
                n = n < 0 ? n % (modulo - 1) + (modulo - 1) : n % (modulo - 1);
                for(; n > 0; a = Mul(a, a), n >>= 1) {
                    if((n & 1) != 0) R = Mul(R, a);
                }
                return R;
            }
            private static long extgcd(long a, long b, ref long x, ref long y) {
                if(b == 0) {
                    x = 1; y = 0; return a;
                }
                var q = a / b;
                var g = extgcd(b, a - q * b, ref x, ref y);
                var z = x - q * y;
                x = y; y = z;
                return g;
            }
            public long Inv(long a) {
                if(a == 0) throw new DivideByZeroException();
                long x = 0, y = 0;
                extgcd(a, modulo, ref x, ref y);
                return mod(x);
            }
            public long Div(long a, long b) => Mul(a, Inv(b));
            public void ExpandFactorialTable(int N) {
                var k = factorialTableLastIndex;
                Array.Resize(ref factorialTable, N + 1);
                for(int i = k + 1; i <= N; i++) {
                    if(i == 0) { factorialTable[i] = 1; continue; }
                    factorialTable[i] = Mul(factorialTable[i - 1], i);
                }
            }
            public long Factorial(int n) {
                if(n > factorialTableLastIndex)
                    ExpandFactorialTable(n);
                return factorialTable[n];
            }
            public long Permutation(int n, int k) {
                if(k < 0 || k > n) throw new InvalidOperationException();
                return Div(Factorial(n), Factorial(n - k));
            }
            public long Combination(int n, int k) {
                if(k < 0 || k > n) throw new InvalidOperationException();
                return Div(Factorial(n), Mul(Factorial(k), Factorial(n - k)));
            }
        }
    }

    static class ExtendClass {
        public static string Join<T>(this T[] X, string separator = " ") => string.Join(separator, X);
    }

    class ConsoleInput {
        private readonly TextReader _stream;
        private readonly char _separator = ' ';
        private readonly Queue<string> inputStream;
        public ConsoleInput(TextReader stream, char separator = ' ') {
            this._separator = separator;
            this._stream = stream;
            inputStream = new Queue<string>();
        }
        public string Read {
            get {
                if(inputStream.Count != 0) return inputStream.Dequeue();
                string[] tmp = _stream.ReadLine().Split(_separator);
                for(int i = 0; i < tmp.Length; ++i)
                    inputStream.Enqueue(tmp[i]);
                return inputStream.Dequeue();
            }
        }
        public string ReadLine { get { return _stream.ReadLine(); } }
        public int ReadInt { get { return int.Parse(Read); } }
        public long ReadLong { get { return long.Parse(Read); } }
        public double ReadDouble { get { return double.Parse(Read); } }
        public string[] ReadStrArray(long N) {
            var ret = new string[N];
            for(long i = 0; i < N; ++i)
                ret[i] = Read;
            return ret;
        }
        public int[] ReadIntArray(long N) { var ret = new int[N]; for(long i = 0; i < N; ++i) ret[i] = ReadInt; return ret; }
        public long[] ReadLongArray(long N) { var ret = new long[N]; for(long i = 0; i < N; ++i) ret[i] = ReadLong; return ret; }
        public double[] ReadDoubleArray(long N) { var ret = new double[N]; for(long i = 0; i < N; ++i) ret[i] = ReadDouble; return ret; }
    }

}