Problem:
Balls and Boxes 10

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 not distinguished from the other.

Each box is not distinguished from the other.

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

Each box can contain an arbitrary number of balls (including zero).

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

5 3

Sample Output 1

5

Sample Input 2

10 5

Sample Output 2

30

Sample Input 3

100 100

Sample Output 3

190569292

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
class Program
{
static long factMax = 200000;//nCkにおけるnの最大値
static long[] factorials = new long[factMax+1];//i!(mod p)をO(n)で先にメモ。
static long[] factorialRs = new long[factMax+1];//i!^-1(mod p), pは素数でO(n)。

	static void Main()
	{
    string[] input = Console.ReadLine().Split(' ');
    long n = long.Parse(input[0]);
    long k = long.Parse(input[1]);
    long p = 1000000007;
  
    factorials[0] = 1;
    factorialRs[factMax] = DivideModFactorial(factMax,p);
    for(long i = 1; i <= factMax; i++)
    {
      factorials[i] = (factorials[i-1]*i)%p;//i!(mod p)
      factorialRs[factMax-i] = (factorialRs[factMax+1-i]*(factMax+1-i))%p;//逆元も先にメモ
    }

    Console.WriteLine(SplitNumber(n,k,p));
	}

  static long SplitNumber(long n, long k, long mod)
  {//区別しないn個の玉を区別しないk個の箱に分ける方法の個数(mod)をO(nk)で返す。
  //数え方は、dp[n,k]は、0個の箱を含む時+dp[n,k-1]、含まない時dp[n-k,k]とする。
    long[,] dp = new long[n+1,k+1];
    
    for(int i = 0; i <= k; i++)
    {
      dp[0,i] = 1;
      for(int j = 1; j <= n; j++)
      {
        if(j-i >= 0) dp[j,i] += dp[j-i,i];
        if(i-1 >= 0) dp[j,i] += dp[j,i-1];
     
        dp[j,i] %= mod;
      }
    }

    return dp[n,k];
  }

  static long MathPow(long x, long a)//戻り値はx^a。O(loga)
  {
    long num = 2;
    long answer = 1;
    long check = a;
    long memo = x;
  
    while(check > 0)
    {
      if(check % num == num / 2)
      {
        check -= num / 2;
        answer *= memo;
      }
    memo *= memo;
    num *= 2;
    }
    return answer;
  }

  static long DivideMod(long x, long a, long p)//戻り値はx^a(mod p)。O(loga)
  {
    long num = 2;
    long answer = 1;
    long check = a;
    long memo = x%p;
    
    while(check > 0)
    {
      if(check % num == num / 2)
      {
        check -= num / 2;
        answer *= memo;
        answer %= p;
      }
    memo *= memo;
    memo %= p;
    num *= 2;
    }
    return answer;
  }

  static long DivideModReverse(long x, long p)//戻り値はx^-1(mod p), pは素数。O(logp)
  {
    long answer = DivideMod(x, p-2, p);
    return answer;
  }

  static long ModFactorial(long x, long p)//戻り値はx!(mod p)
  {
    long answer = 1;
    for(int i = 2; i <= x; i++)
    {
      answer *= i;
      answer %= p;
    }
    return answer;
  }

  static long DivideModFactorial(long x, long p)//戻り値はx!^-1(mod p), pは素数
  {
    long answer = 1;
    for(long i = x; i >= 2; i--)
    {
      answer *= DivideModReverse(i, p);
      answer %= p;
    }
    return answer;
  }

  static long Comb(long a, long b, long p)//組み合わせC(a,b)(mod p)をO(1)で返す
  {
    if(a-b < 0) return 0;//引数a-bが負なら0を返す
    long answer = 1;
    answer *= factorials[a];
    answer %= p;
    answer *= factorialRs[a-b];
    answer %= p;
    answer *= factorialRs[b];
    answer %= p;
    return answer;
  }
  
}