#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个苹果
即下图所示的转化方程

京公网安备 11010502036488号