POJ 1664 放苹果( 递推关系 )

时间:2023-11-25 21:54:02

**链接:****传送门 **

思路:苹果m个,盘子n个。假设 f ( m , n ) 代表 m 个苹果,n个盘子有 f ( m , n ) 种放法。

  • 根据 n 和 m 的关系可以进一步分析:

    1. 特殊的 n = 1 || m = 1 || n = 0 时只有一种方法

    2. 当 m < n时,即使苹果每个盘子放一个也没法放满所有盘子,题目允许有的盘子空着不放,所以我们可以将空盘子去掉,即 f ( m , n ) = f ( m , m )

    3. 当 m >= n时,这时候有两种情况:

      1. n 个盘子中有一个空盘子,当有空盘子时,f ( m , n ) = f ( m , n - 1 ) ,这时候问题出现了,f ( m , n-1 ) 代表的意思是m个苹果放到n-1个盘子中,那还可能有 2 个或者 n 个空盘子呢,请看 iii 。
      2. n个盘子中没有空盘子,当没有空盘子时也就是说每个盘子中至少有一个苹果,先把所有盘子填满,这时候会剩下 m - n 个苹果,所以现在问题变成了 m - n 个苹果放在 n 个盘子有多少种方法,即 f ( m - n , n )。
    4. 解释 m >= n 时最后的疑问:因为 m >= n , 所以 m >= n - 1 必然成立,也就是说 f ( m , n - 1 )这个状态也会面临两种情况,即 m >= n 时的 i 和 ii,当面临 i 时可得 f ( m , n - 1 ) = f ( m , n - 2 ),所以有 2 个空盘子的情况是在 1 个空盘子前就解决了,所以现在只需要考虑 1 个空盘子的情况就好了。

  • 根据如上所分析,递推关系如下:

POJ 1664 放苹果( 递推关系 )


/*************************************************************************
> File Name: poj1664.cpp
> Author: WArobot
> Blog: http://www.cnblogs.com/WArobot/
> Created Time: 2017年05月10日 星期三 18时33分00秒
************************************************************************/ #include<cstdio>
using namespace std; int fun(int m,int n){
if( n==1 || m==1 || n==0 ) return 1;
if(m<n) return fun(m,m);
else return fun(m-n,n)+fun(m,n-1);
}
int main(){
int t , m , n;
scanf("%d",&t);
while(t--){
scanf("%d%d",&m,&n);
printf("%d\n",fun(m,n));
}
return 0;
}