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++14 (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template <typename NumType, int LIMIT = 2000010>
struct Combination {
    vector<NumType> fact_, finv_;

    Combination() : fact_(LIMIT+1), finv_(LIMIT+1) {
        fact_[0] = finv_[LIMIT] = NumType(1);
        for(int i=1; i<=LIMIT; i++) {
            fact_[i] = fact_[i-1] * NumType(i);
        }
        
        finv_[LIMIT] /= fact_[LIMIT];
        for(int i=LIMIT-1; i>=0; i--) {
            finv_[i] = finv_[i+1] * NumType(i+1);
        }
    }

    inline NumType fact(int k) const { return fact_[k]; }
    inline NumType finv(int k) const { return finv_[k]; }
    NumType P(int n, int r) const {
        if(r < 0 or n < r) return NumType(0);
        return fact_[n] * finv_[n-r];
    }
    NumType C(int n, int r) const {
        if(r < 0 or n < r) return NumType(0);
        return fact_[n] * finv_[n-r] * finv_[r];
    }
    // 重複組み合わせ
    NumType H(int n, int r) const {
        if(n < 0 or r < 0) return NumType(0);
        return r == 0 ? NumType(0) : C(n + r - 1, r);
    }
    // ベル数 (区別できる n 個のボールを区別できない k 個以下の箱に分割)
    // B(n, n) := n 個のボールを任意個のグループに分割する場合の数
    NumType B(int n, int k) const {
        if(n == 0) return NumType(1);
        k = min(n, k);
        NumType ret(0);
        vector<NumType> pref(k + 1); pref[0] = NumType(1);
        for(int i=1; i<=k; i++) {
            if(i & 1) pref[i] = pref[i-1] - finv_[i];
            else pref[i] = pref[i-1] + finv_[i];
        }
        for(int i=1; i<=k; i++) {
            // 累乗が必要なので適宜書き換える？
            // ModInt 使うならこれでいい
            ret += NumType(i).pow(n) * finv_[i] * pref[k-i];
        }
        return ret;
    }
    // スターリング数 (区別できる n 個のボールを区別できない k 個の箱に分割)
    NumType S(int n, int k) const {
        if(n < k) return NumType(0);
        NumType ans(0);
        for(int i=0; i<=k; i++) {
            NumType val = C(k, i) * NumType(i).pow(n);
            if((k - i) % 2) ans -= val;
            else ans += val;
        }
        return ans * finv_[k];
    }
};

// P(n, k) := n の k 分割 (k 個の 0 以上の整数の和)
template <typename NumType, int LIMIT = 3010>
struct Partition {
    vector< vector<NumType> > dp;
    Partition() : dp(LIMIT, vector<NumType>(LIMIT)) {
        for(int k=0; k<LIMIT; k++) dp[0][k] = NumType(1);
        for(int i=1; i<LIMIT; i++) {
            for(int j=1; j<LIMIT; j++) {
                dp[i][j] += dp[i][j-1];
                if(i-j >= 0) dp[i][j] += dp[i-j][j];
            }
        }
    }
    inline NumType get(int n, int k) {
        if(n < 0 or k < 0) return NumType(0);
        return dp[n][k];
    }
};

// ModInt begin

using ll = long long;
template<ll mod>
struct ModInt {
    ll v;
    ll mod_pow(ll x, ll n) const {
        return (!n) ? 1 : (mod_pow((x*x)%mod,n/2) * ((n&1)?x:1)) % mod;
    }
    ModInt(ll a = 0) : v() {
        if(a >= mod) v = a % mod;
        else if(a < 0) v = mod - (-a % mod);
        else v = a;
    }
    ModInt operator+ ( const ModInt& b ) const {
        return (v + b.v >= mod ? ModInt(v + b.v - mod) : ModInt(v + b.v));
    }
    ModInt operator- ( const ModInt& b ) const {
        return (v - b.v < 0 ? ModInt(v - b.v + mod) : ModInt(v - b.v));
    }
    ModInt operator* ( const ModInt& b ) const {return (v * b.v) % mod;}
    ModInt operator/ ( const ModInt& b ) const {return (v * mod_pow(b.v, mod-2)) % mod;}
    
    bool operator== ( const ModInt &b ) const {return v == b.v;}
    ModInt& operator+= ( const ModInt &b ) {
        v += b.v;
        if(v >= mod) v -= mod;
        return *this;
    }
    ModInt& operator-= ( const ModInt &b ) {
        v -= b.v;
        if(v < 0) v += mod;
        return *this;
    }
    ModInt& operator*= ( const ModInt &b ) {
        (v *= b.v) %= mod;
        return *this;
    }
    ModInt& operator/= ( const ModInt &b ) {
        (v *= mod_pow(b, mod-2)) %= mod;
        return *this;
    }
    ModInt pow(ll x) { return ModInt(mod_pow(v, x)); }
    operator int() const { return int(v); }
    operator long long int() const { return v; }
};

template<ll mod>
ostream& operator<< (ostream& out, ModInt<mod> a) {return out << a.v;}
template<ll mod>
istream& operator>> (istream& in, ModInt<mod> a) {
    in >> a.v;
    return in;
}

// ModInt end

using mint = ModInt<1000000007>;

void DPL_5_A() {
    int N, K; cin >> N >> K;
    mint ans(K);
    cout << ans.pow(N) << endl;
}

void DPL_5_B() {
    int N, K; cin >> N >> K;
    Combination<mint> comb;
    cout << comb.P(K, N) << endl;
}

void DPL_5_C() {
    int N, K; cin >> N >> K;

    Combination<mint> comb;
    mint ans = comb.S(N, K) * comb.fact(K);
    cout << ans << endl;
}

void DPL_5_D() {
    int N, K; cin >> N >> K;
    Combination<mint> comb;
    cout << comb.H(K, N) << endl;
}

void DPL_5_E() {
    int N, K; cin >> N >> K;
    Combination<mint> comb;
    cout << comb.C(K, N) << endl;
}

void DPL_5_F() {
    int N, K; cin >> N >> K;
    Combination<mint> comb;
    cout << comb.C(N-1, K-1) << endl;
}

void DPL_5_G() {
    int N, K; cin >> N >> K;
    Combination<mint> comb;
    cout << comb.B(N, K) << endl;
}

void DPL_5_I() {
    int N, K; cin >> N >> K;
    Combination<mint> comb;
    cout << comb.S(N, K) << endl;
}

void DPL_5_J() {
    int N, K; cin >> N >> K;
    Partition<mint> part;
    cout << part.get(N, K) << endl;
}

void DPL_5_L() {
    int N, K; cin >> N >> K;
    Partition<mint> part;
    cout << part.get(N-K, K) << endl;
}

int main() {
    // DPL_5_A();
    // DPL_5_B();
    // DPL_5_C();
    // DPL_5_D();
    // DPL_5_E();
    // DPL_5_F();
    // DPL_5_G();
    // DPL_5_I();
    DPL_5_J();
    // DPL_5_L();
}