1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 #include <math.h>
4 #include <algorithm>
5 #include <stdlib.h>
6 #include <vector>
7 #include <map>
8 #include <queue>
9 #include <string>
10 #include <iostream>
11 #include <ctype.h>
12 #include <string.h>
13 #include <set>
14 #include <stack>
15 #include<functional>
16 using namespace std;
17 #define Size 10001
18 #define maxn 1<<30
19 int dp[Size][11];
20 /*表示 i个苹果放在j个盘子里面的所能放的种类
21 dp[i][j]=dp[i][j-1]+dp[i-j][j]
22 i个苹果放在j个盘子里面,
23 只少有一个盘子为空时, dp[i][j-1]
24 没有一个盘子为空时 ,dp[i-j][j],与每个盘子都去掉一个苹果的方法是一样的
25 如果盘子数大于苹果数目那么即为i>j
26 dp[i][j]=dp[j][j]
27
28 找出口的方法!!就是找出最初开始填的元素进行推导
29 首先
30 dp(1,1)=dp(1,0)+dp(0,1) //dp(1,1) 是我们填表要填的第一个元素 其值为1
31 dp(2,1)=dp(2,0)+dp(1,1) //其值为1 很明显出口是m==0 和n==0 节上面两个方程可以知道 dp(i,0)=0 dp(0,j)=1;
32 dp(2,2)=dp(2,0)+dp(1,1)
33 */
34 int solve(int n, int m){
35 if (dp[n][m] != -1) return dp[n][m];
36 if (n == 0) {//看出口,一条路是n逐渐减小, 最终可能减到0
37 dp[n][m] = 1;
38 return 1;
39 }
40 if (m == 0) {
41 dp[n][m] = 0;
42 return 0;
43 }
44 if (m > n) {
45 dp[n][m]= solve(n, n);
46 return dp[n][m];
47 }
48
49 dp[n][m]=solve(n - m, m) + solve(n, m - 1);//能走到这肯定是n-m>=1,而出口条件 dp[1][m]因为题目给的条件有水果数目为1的情况,不需要我们定义,其值为1
50 return dp[n][m];
51
52 }
53 int main(){
54
55 int T;
56 cin >> T;
57 while (T--){
58 int n, m;
59 cin >> n >> m;
60 for (int i = 0; i <= n; i++)
61 for (int j = 0; j <= m; j++)
62 dp[i][j] = -1;
63 cout << solve(n, m) << endl;
64 }
65 system("pause");
66 return 0;
67 }