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 }