#include <iostream>
#include<vector>
using namespace std;
int main() {
    int m,n;
    while(cin>>m>>n){
    vector<vector<int>> dp;
    dp=vector<vector<int>>(m+1,vector<int>(n+1));
    for(int i=0;i<=m;i++){
        dp[i][0]=0;
        dp[i][1]=1;
    }
    for(int i=0;i<=n;i++){
        dp[0][i]=1;
        dp[1][i]=1;
    }
    for(int i=2;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(i>=j)dp[i][j]=dp[i-j][j]+dp[i][j-1];
            else dp[i][j]=dp[i][i];
        }
    }
    cout<<dp[m][n]<<endl;
    }
    return 0;
}
// 64 位输出请用 printf("%lld")

经典动态规划:

m个苹果,n个盘子。由于题目的要求,即1,1,5与5,1,1等价

首先考虑边界情况

因此当只有1个苹果时,对n个盘子,都是由n-1个空盘子和1个装有1个苹果的盘子组成的,无论这一个非空盘子位于第几个,摆放方式均等价,因此,当苹果只有一个的时候,只有一种摆放方式。

同理,当没有苹果的时候,盘子均为空摆放方式也只有一种。

而当只有一个盘子的时候,无论苹果有多少个,都只能放在这一个盘子里,因此摆放方式也只有一种

当没有盘子的时候,无法摆放,为0种;

普遍情况下:

当所拥有的苹果数m大于等于盘子数n的时候,分为有空盘子和没有空盘子两种情况

若没有空盘子,为保证没有空盘子那么我们将n个盘子中每一个都放一个苹果,在这种情况下,苹果数目变为m-n;问题转化为在n个盘子中放m-n个苹果有多少种放置方式

若存在盘子为空,则至少有一个盘子为空,问题转化为在n-1个盘子种放m个苹果

在拥有的苹果数m小于盘子数n时,必然有m-n个盘子为空,问题转化为在m个盘子中放m个苹果

即下图所示的转化方程