坑了我好久,乍看很简单,记忆化搜索结果爆栈,然后改成递推之后WA 。 后来发现,是在计算m=3的数据时出现了错误,因为当m=3时,即使n很小,结果也会很大,所以无法利用m=2时的结果递推,要怎么办呢? 将m=2的结果打印出来可以发现这是一个等差数列,通项为S(n) = 2*n + 3;
这有什么用呢? 我们可以发现,当 m=3时由递推式可以写成A(m,n) = A(2,A(m,n-1)) = 2*A(m,n-1) + 3; 所以只要知道了A(3,0),我们就能递推出所有m=3时的值了 。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<list>
#include<cmath>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const int INF = 100000000;
const int mod = 1000000;
const long long maxn = 8000000+1;
int T,n,m,kase = 0, d[5][maxn] = {0};
int main() {
for(int i=0;i<3;i++)
for(int j=0;j<=1000000;j++) {
if(i==0) d[i][j] = j+1;
else if(i > 0 && j == 0) d[i][j] = d[i-1][1];
else if(i > 0 && j > 0) d[i][j] = d[i-1][d[i][j-1]];
}
d[3][0] = d[2][1];
for(int j=1;j<=24;j++) {
d[3][j] = 2*d[3][j-1] + 3;
}
while(~scanf("%d%d",&m,&n)) {
printf("%d\n",d[m][n]);
}
return 0;
}