写了三种版本。
第一种:普通版
#include<cstdio>
#include<cstring>
int dfs(int M,int N)
{
if(N==1||M==0)
return 1;
if(M>=N)
return dfs(M-N,N)+dfs(M,N-1);
else
return dfs(M,M);
}
int main()
{
int T,M,N;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&M,&N);
printf("%d\n",dfs(M,N));
}
}
第二种:记忆化搜索
#include<cstdio>
#include<cstring>
int dp[16][16];
int dfs(int M,int N)
{
if(dp[M][N]!=-1)
return dp[M][N];
if(N==1||M==0)
return dp[M][N]=1;
if(M>=N)
return dp[M][N]=dfs(M-N,N)+dfs(M,N-1);
else
return dp[M][N]=dfs(M,M);
}
int main()
{
int T,M,N;
memset(dp,-1,sizeof(dp));
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&M,&N);
printf("%d\n",dfs(M,N));
}
}
第三种:递推
#include<cstdio>
#include<cstring>
int dp[16][16];
int main()
{
int T,n,m;
scanf("%d",&T);
memset(dp,0,sizeof(dp));
for(int i=1;i<=10;i++)
{
for(int j=1;j<=10;j++)
{
if(i<j)
dp[i][j]=dp[i][i];
else
if(i==j)
dp[i][j]=dp[i][j-1]+1;
else
dp[i][j]=dp[i-j][j]+dp[i][j-1];
}
}
while(T--)
{
scanf("%d%d",&n,&m);
printf("%d\n",dp[n][m]);
}
}