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