`
richard_ma
  • 浏览: 16362 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

POJ1579递归函数定义

阅读更多
Function Run Fun

http://poj.org/problem?id=1579

Description
We all love recursion! Don't we?

Consider a three-parameter recursive function w(a, b, c):

if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns:
1

if a > 20 or b > 20 or c > 20, then w(a, b, c) returns:
w(20, 20, 20)

if a < b and b < c, then w(a, b, c) returns:
w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)

otherwise it returns:
w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)

This is an easy function to implement. The problem is, if implemented directly, for moderate values of a, b and c (for example, a = 15, b = 15, c = 15), the program takes hours to run because of the massive recursion.

Input
The input for your program will be a series of integer triples, one per line, until the end-of-file flag of -1 -1 -1. Using the above technique, you are to calculate w(a, b, c) efficiently and print the result.

Output
Print the value for w(a,b,c) for each triple.

Sample Input
1  1  1
2  2  2
10 4  6
50 50 50
-1 7  18
-1 -1 -1

Sample Output
w(1, 1, 1) = 2
w(2, 2, 2) = 4
w(10, 4, 6) = 523
w(50, 50, 50) = 1048576
w(-1, 7, 18) = 1

Source
Pacific Northwest 1999

很明显,这里的函数w定义就是个递归函数。不过w的递归过于复杂,如果直接按照题意编写模拟函数,肯定是TLE的。

这样在递归过程中记录一下中间结果,如果需要用到的时候则可以查表。由于有当a,b,c大于20的时候都视为20,则这个表是三维,最大元素为20的数组。

下面代码使用e数组作为表,每次先看是否在表中有对应结果,如果有则直接使用,没有就按照递归计算,计算完成后同时记录结果到表中。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int e[21][21][21];

int fun (int a, int b, int c)
{

    if (a <= 0 || b <= 0 || c <= 0) return 1;
    if (a > 20 || b > 20 || c > 20) return fun(20, 20, 20);
    if (a < b && b < c) {
        if (e[a][b][c]) return e[a][b][c];
        else 
            e[a][b][c] = fun(a, b, c-1) + fun(a, b-1, c-1) - fun(a, b-1, c);
    } else {
        if (e[a][b][c]) return e[a][b][c];
        else
            e[a][b][c] = fun(a-1, b, c) + fun(a-1, b-1, c) + fun(a-1, b, c-1) - fun(a-1, b-1, c-1);
    }

    return e[a][b][c];
}

int main (int argc, char const* argv[])
{
    int a, b, c;
    memset(e, 0, sizeof(e));

    while (1) {
        scanf("%d %d %d", &a, &b, &c);
        if (a == -1 && b == -1 && c == -1) {
            break;
        }

        printf("w(%d, %d, %d) = %d\n", a, b, c, fun(a, b, c));
    }

    return 0;
}
分享到:
评论

相关推荐

    POJ1664放苹果

    代码中定义了一个递归函数`f`,该函数接受两个参数M和N,并返回所有可能的分配方案的数量。此外,主函数`main`用于读取输入并调用递归函数,最终输出结果。 ### 示例分析 根据样例输入输出,当M=7且N=3时,输出为8...

    poj2488.rar_poj24_poj2488_方向模板法

    3. 设计算法的回溯框架:定义一个递归函数,初始化初始状态,然后进入递归过程。 4. 深度优先搜索:每次选择一个可能的解,并继续尝试下一个解,直到找到有效解或所有可能的解都尝试过。 5. 剪枝:在搜索过程中,...

    poj编程指导

    书中还详细介绍了函数的定义、调用、参数传递、返回值以及如何使用库函数和头文件。标准输入输出是通过printf函数和scanf函数进行的,这些是编写控制台程序时必不可少的部分。在C/C++中,了解全局变量和局部变量的...

    POJ滑雪问题

    通过寻找二维数组中的最长递增子序列,我们可以学习到如何运用动态规划优化复杂度,以及如何设计递归函数来处理这类问题。这种问题解决技巧在处理类似的最优化问题时非常有用,如最长公共子序列、最长递增子序列等。

    POJ 分类题目

    - **定义**:递归是将问题分解成更小的问题重复解决;分治法则是在递归的基础上,将问题分割为两个或更多的子问题,独立解决后再合并结果。 - **示例题目**: - poj1164 - poj1941 - poj2282 - poj2299 - poj...

    经典 的POJ 分类

    - POJ 3176、POJ 1080:复杂的状态空间定义与状态转移。 ### 数学问题 #### 组合数学 - **题目示例**: - POJ 3252、POJ 1850:组合数学原理的应用。 - POJ 1019、POJ 1942:组合计数问题。 #### 几何问题 - *...

    西工大c语言poj答案

    2. **函数**:函数的定义、调用、参数传递,以及递归函数的概念。 3. **指针**:理解指针的本质,如何声明、初始化和使用指针,以及指针在数组、字符串和函数中的应用。 4. **内存管理**:动态内存分配(malloc/...

    POJ 1077 算法

    标题中的“POJ 1078 算法”指的是北京大学在线判题系统...总的来说,POJ 1077 算法题目的解决过程涵盖了C++编程基础、数据结构、图搜索算法、启发式函数设计等多个方面的知识,是检验和提升算法能力的一个好练习。

    西北工业大学Poj100题

    2. **函数**:函数的定义、调用、参数传递,以及递归函数的使用。 3. **指针**:指针的概念、指针变量的声明与赋值、指针运算、动态内存分配与释放、指针作为函数参数。 4. **数组与字符串**:一维和多维数组的...

    POJ1013 C解法

    掌握变量声明、控制流程(如if-else、for、while)、函数定义和调用等基本概念是必要的。 2. **编程竞赛环境**:了解POJ平台的提交和评测机制,比如输入输出格式、时间限制和内存限制,这些都会影响到算法设计和...

    poj1990.rar_POJ 19_poj_poj19

    在实际解题时,我们通常会先定义两个树状数组,一个用于存储原始数据,另一个用于存储某种衍生信息,例如累计和、最大值或最小值等。 解题的关键在于如何正确地设计树状数组的更新和查询函数。对于树状数组的更新,...

    西北工业大学c语言实验课答案(源代码) poj

    2. **函数**:C语言中的函数定义、调用,参数传递,以及递归函数的理解与应用。 3. **指针**:指针的概念,指针变量的声明、初始化,指针操作,指针作为函数参数,动态内存分配与释放(malloc和free)。 4. **数组...

    poj 1191 经典dp 源代码

    - `solve()` 函数是核心递归函数,用于计算最优解。 - 当 n=1 时,直接返回已计算的状态。 - 对于较大的 n,采用水平或垂直分割的方法递归求解,并记录最佳结果。 #### 3. 输入输出 ```cpp int main() { double ...

    poj 2376 解题报告

    为了实现这个算法,解题报告中提到使用了结构体`COW`来存储每头牛的清洁区间,并定义了一个比较函数`cmp`用于排序。在主函数`main`中,通过循环读取输入的牛的数量`n`和地板长度`t`,然后对每组数据执行上述贪心策略...

    C++POJ前四季

    5. **函数与递归**:函数是代码的复用单元,而递归则是函数调用自身的一种方法,常用于解决复杂问题,如树的遍历、斐波那契数列等。 6. **结构体与类**:C++支持面向对象编程,结构体和类是封装数据和方法的工具。...

    线段树练习POJ 3264

    1. 线段树类的定义,可能包含成员变量(如数组存储线段树节点的值)和构造函数。 2. 区间查询方法,接收区间的起始和结束位置,返回该区间的特定信息(如最值或和)。 3. 区间更新方法,接收更新的位置和新的值,...

    西工大poj100题

    1. **基础语法**:包括变量声明、类型转换、运算符优先级、流程控制(if-else、switch-case、for、while、do-while)、函数定义与调用、返回值等。 2. **数据结构**:涉及基本的数据结构如数组、链表、栈、队列,...

    POJ1905-Expanding Rods

    - 可能会使用递归函数来实现自顶向下的动态规划,但为了效率,通常会用一个记忆化搜索的数组来存储中间结果,避免重复计算。 解题报告的DOC文档则会详细解释以上步骤,包括如何理解问题、为什么选择动态规划、如何...

    动态规划算法poj1088滑雪实验报告

    2. 定义函数`DP(i, j)`,表示当前位置`(i, j)`的最大滑行距离。如果`cnt[i][j]`已经有值,则直接返回,否则进行计算。 3. 对于当前点`(i, j)`,检查其上下左右四个相邻点。如果相邻点的高度更低,那么以该相邻点为...

Global site tag (gtag.js) - Google Analytics