1. 题目描述

1.1. Limit

Time Limit: 1000 ms

Memory Limit: 131,072 kB

1.2. Problem Description

阿克曼(Arkmann)函数 A ( m , n ) A(m, n) A(m,n) 中,m与n的定义域是非负整数且本题中 m 3 m \le 3 m3 n 16 n\le 16 n16

函数的定义为:

a k m ( m , n ) = { <mstyle displaystyle="true" scriptlevel="0"> n + 1 </mstyle> <mstyle displaystyle="true" scriptlevel="0"> , ( m = 0 ) </mstyle> <mstyle displaystyle="true" scriptlevel="0"> </mstyle> <mstyle displaystyle="true" scriptlevel="0"> a k m ( m 1 , 1 ) </mstyle> <mstyle displaystyle="true" scriptlevel="0"> , ( m > 0 , n = 0 ) </mstyle> <mstyle displaystyle="true" scriptlevel="0"> </mstyle> <mstyle displaystyle="true" scriptlevel="0"> a k m ( m 1 , a k m ( m , n 1 ) ) </mstyle> <mstyle displaystyle="true" scriptlevel="0"> , ( m > 0 , n > 0 ) </mstyle> <mstyle displaystyle="true" scriptlevel="0"> </mstyle> akm(m, n) = {\left\{ \begin{aligned} n+1 & , (m = 0)& \\ akm(m - 1, 1) & , (m > 0, n = 0)& \\ akm(m - 1, akm(m, n - 1)) & , (m > 0, n > 0)& \\ \end{aligned}\right. } akm(m,n)=n+1akm(m1,1)akm(m1,akm(m,n1)),(m=0),(m>0,n=0),(m>0,n>0)


1.3. Input

两个整数 m m m n n n


1.4. Output

一个整数, a k m ( m , n ) akm(m,n) akm(m,n)的结果


1.5. Sample Input

1 1

1.6. Sample Output

3

1.7. Source

51Nod 2656 阿克曼函数


2. 解读

如果直接使用 a k m ( m , n ) akm(m,n) akm(m,n) 进行计算,最后一个点会超时。这时考虑到题目所给的数据范围 0 m 3 0 \le m \le 3 0m3 0 n 16 0 \le n\le 16 0n16 比较小,带入一些数字尝试找出 a k m ( m , n ) akm(m,n) akm(m,n) 的规律。

m m m n n n a k m ( m , n ) akm(m,n) akm(m,n) m m m n n n a k m ( m , n ) akm(m,n) akm(m,n)
1 1 3 2 1 5
1 2 4 2 2 7
1 3 5 2 3 9
1 n n n n + 2 n+2 n+2 2 n n n 2 n + 3 2n+3 2n+3
m m m n n n a k m ( m , n ) akm(m,n) akm(m,n)
3 1 13
3 2 29
3 3 61
3 4 125
3 n 2 n + 3 3 2^{n+3} - 3 2n+33

再将找出的规律写成一个函数进行计算即可。

3. 代码

#include <algorithm>
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;

int akm(int m, int n)
{
    if (m == 0) {
        return n + 1;
    } else if (m > 0 && n == 0) {
        return akm(m - 1, 1);
    } else if (m > 0 && n > 0) {
        return akm(m - 1, akm(m, n - 1));
    } else {
        return 0;
    }
}


long long calculate(int m, int n)
{
    if (m == 0) {
        return n + 1;
    } else if (m == 1) {
        return n + 2;
    } else if (m == 2) {
        return 2 * n + 3;
    } else if (m == 3) {
        return pow(2, n + 3) - 3;
    } else {
        return 0;
    }
}

int main()
{
    // test case
    int m, n;
    scanf("%d %d", &m, &n);
    // 计算
    printf("%lld", calculate(m, n));
}

联系邮箱:curren_wong@163.com

Github:https://github.com/CurrenWong

欢迎转载/Star/Fork,有问题欢迎通过邮箱交流。