杭电上的一道基础的母函数的题目
这里介绍用递归加记忆化的方式完成
参考博客: https://www.bbsmax.com/A/kmzLnaXW5G/
这里首先定义 F(n,m) 为将整数N 划分为一系列整数的和,其中最大的加数不超过M
根据题目意思, 1<=N<=120;
有以下几种情况
-
N=1 或 M=1
这时,划分的情况只能是 1 或者 1+1+1+1+1…
F(1,1)=F(1,M)=F(N,1)=1 -
N<M
显然,划分的情况只能是 N=N 这一种情况
F(N,M)=F(N,N)=1 -
N==M
-
当加数包含 M 时,只有一种情况 N=N
-
当加数不包含 M 时 ,F(N,M)=F(N,M-1)
F(N,M)=F(N,M-1)+1
- N>M
- 当加数包含 M 时, N=M+X1+X2+…
F(N,M)=F(N-M,M)=F(N-M,N-M) - 当加数不包含 M 时 ,F(N,M)=F(N,M-1)
F(N,M)=F(N,M-1)
附上代码:
#include<bits/stdc++.h>
#define MAXM 131
using namespace std;
int num[MAXM][MAXM] ;
int solve(int n,int m)
{
if(m==1 || n==1 )
{
if(num[n][m]==-1) return num[n][m]=1;
else return num[n][m];
}
else if(m>n)
{
if(num[n][m]==-1) return num[n][m]=solve(n,n);
else return num[n][m];
}
else if(n==m) {
if(num[n][m]==-1) return num[n][m]=solve(n,m-1)+1;
else return num[n][m];
}
else {
if(num[n][m]==-1) return num[n][m]=solve(n,m-1)+solve(n-m,m);
else return num[n][m];
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(num,-1,sizeof(num));//初始化数组为-1
printf("%d\n",solve(n,n));
}
return 0;
}