看题传送门 :http://poj.org/problem?id=1664
沃尼玛这题如此之水当时我居然想了好长时间……又是剪枝又是去重的……
其实这个题是很简单的动态规划,根据题意,这个问题可以分成两种状态:
1.当nPlate > nApple时,此时必然有(nPlate - nApple)个盘子是空的,即使把这几个必空的盘子去掉也不会影响最后的结果,状态转移方程为F(nPlate, nApple) = F(nApple, nApple)。
2.当nPlate < nApple时,这种状态,其实是两种状态的和,一种是故意空出一个盘子不放苹果,另一种状态是每一个盘子都至少有一个苹果,这时苹果的数量就可以变为(nApple - nPlate)。
状态转移方程为F(nPlate, nApple) = F(nPlate-1, nApple) + F(nPlate, nApple - nPlate)
关于递归边界,我们可以考虑这几种情况。第一种是这时候不管还有几个苹果,只剩一个盘子了,方法可以加一。第二种情况是没有苹果了,不管有没有盘子,这也是一种结束情况,加一。第三种情况是还剩一个苹果,不管还剩几个盘子,就只有一种方法。
下面上一波C艹实现
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
//此题利用动态规划解题,可以找出状态转移方程,最小子问题可以分为两种
int DFS(int nPlate, int nApple)
{
if(nPlate == 1 || nApple == 0 || nApple == 1)
return 1;
else if(nPlate > nApple)
return DFS(nApple, nApple);
else
return DFS(nPlate-1,nApple) + DFS(nPlate, nApple-nPlate);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int M, N;
scanf("%d %d",&M, &N);
printf("%d\n",DFS(N, M));
}
}