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数组作为表,每次先看是否在表中有对应结果,如果有则直接使用,没有就按照递归计算,计算完成后同时记录结果到表中。
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; }
发表评论
-
fhloj1051 投票
2013-07-04 19:42 0投票 源文件: b(.bas/.c/.cpp/.pas) 输 ... -
fhloj1050 足球赛
2013-07-04 19:36 605足球赛 源文件: a(.bas/.c/.cpp/.pas) ... -
fhloj1092 五子棋
2013-07-04 12:01 739五子棋 源文件: gobang(.bas/.c/.cpp/ ... -
fhloj1091 拼单词
2013-07-04 11:53 754拼单词 源文件: words ... -
fhloj1090 21点游戏
2013-07-04 11:44 64221点游戏 源文件: poker(.bas/.c/.cpp ... -
fhloj1089 帮奶奶算帐
2013-07-04 11:17 607帮奶奶算账 源代码:bill.bas/pas 输入文件:bil ... -
hdu1019 gcd和lcm
2012-12-06 15:09 823Least Common Multiple http://a ... -
hdu1021 推理规律
2012-12-06 09:24 940Fibonacci Again http://acm.hdu ... -
hud1008 电梯 迭代模拟计算
2012-12-04 18:24 1049Elevator http://acm.hdu.edu.cn ... -
hdu1001 求和
2012-12-03 22:05 785Sum Problem http://acm.hdu.edu ... -
hdu1000 A+B
2012-12-03 18:37 871A + B Problem http://acm.hdu.e ... -
hdu2035 乘方取余
2012-12-02 18:02 1161人见人爱A^B http://acm.hdu.edu.cn/ ... -
hdu2034 差集
2012-12-02 17:43 865人见人爱A-B http://acm.hdu.edu.cn/ ... -
hdu2033 时间计算
2012-12-02 16:24 914人见人爱A+B http://acm.hdu.edu.cn/ ... -
HDU1003最大连续子序列和
2012-12-01 15:08 1449Max Sum http://acm.hdu.edu.cn/ ... -
hdu2081 字符串拼接
2012-12-01 14:35 870手机短号 http://acm.hdu.edu.cn/sho ... -
poj1163 树型结构动态规划和最大路径
2012-11-30 22:05 1198The Triangle http://poj.org/pr ... -
POJ1050 最大子矩阵
2012-11-30 11:34 1228To the Maxhttp://poj.org/proble ...
相关推荐
代码中定义了一个递归函数`f`,该函数接受两个参数M和N,并返回所有可能的分配方案的数量。此外,主函数`main`用于读取输入并调用递归函数,最终输出结果。 ### 示例分析 根据样例输入输出,当M=7且N=3时,输出为8...
3. 设计算法的回溯框架:定义一个递归函数,初始化初始状态,然后进入递归过程。 4. 深度优先搜索:每次选择一个可能的解,并继续尝试下一个解,直到找到有效解或所有可能的解都尝试过。 5. 剪枝:在搜索过程中,...
书中还详细介绍了函数的定义、调用、参数传递、返回值以及如何使用库函数和头文件。标准输入输出是通过printf函数和scanf函数进行的,这些是编写控制台程序时必不可少的部分。在C/C++中,了解全局变量和局部变量的...
通过寻找二维数组中的最长递增子序列,我们可以学习到如何运用动态规划优化复杂度,以及如何设计递归函数来处理这类问题。这种问题解决技巧在处理类似的最优化问题时非常有用,如最长公共子序列、最长递增子序列等。
- **定义**:递归是将问题分解成更小的问题重复解决;分治法则是在递归的基础上,将问题分割为两个或更多的子问题,独立解决后再合并结果。 - **示例题目**: - poj1164 - poj1941 - poj2282 - poj2299 - poj...
- POJ 3176、POJ 1080:复杂的状态空间定义与状态转移。 ### 数学问题 #### 组合数学 - **题目示例**: - POJ 3252、POJ 1850:组合数学原理的应用。 - POJ 1019、POJ 1942:组合计数问题。 #### 几何问题 - *...
2. **函数**:函数的定义、调用、参数传递,以及递归函数的概念。 3. **指针**:理解指针的本质,如何声明、初始化和使用指针,以及指针在数组、字符串和函数中的应用。 4. **内存管理**:动态内存分配(malloc/...
标题中的“POJ 1078 算法”指的是北京大学在线判题系统...总的来说,POJ 1077 算法题目的解决过程涵盖了C++编程基础、数据结构、图搜索算法、启发式函数设计等多个方面的知识,是检验和提升算法能力的一个好练习。
2. **函数**:函数的定义、调用、参数传递,以及递归函数的使用。 3. **指针**:指针的概念、指针变量的声明与赋值、指针运算、动态内存分配与释放、指针作为函数参数。 4. **数组与字符串**:一维和多维数组的...
掌握变量声明、控制流程(如if-else、for、while)、函数定义和调用等基本概念是必要的。 2. **编程竞赛环境**:了解POJ平台的提交和评测机制,比如输入输出格式、时间限制和内存限制,这些都会影响到算法设计和...
在实际解题时,我们通常会先定义两个树状数组,一个用于存储原始数据,另一个用于存储某种衍生信息,例如累计和、最大值或最小值等。 解题的关键在于如何正确地设计树状数组的更新和查询函数。对于树状数组的更新,...
2. **函数**:C语言中的函数定义、调用,参数传递,以及递归函数的理解与应用。 3. **指针**:指针的概念,指针变量的声明、初始化,指针操作,指针作为函数参数,动态内存分配与释放(malloc和free)。 4. **数组...
- `solve()` 函数是核心递归函数,用于计算最优解。 - 当 n=1 时,直接返回已计算的状态。 - 对于较大的 n,采用水平或垂直分割的方法递归求解,并记录最佳结果。 #### 3. 输入输出 ```cpp int main() { double ...
为了实现这个算法,解题报告中提到使用了结构体`COW`来存储每头牛的清洁区间,并定义了一个比较函数`cmp`用于排序。在主函数`main`中,通过循环读取输入的牛的数量`n`和地板长度`t`,然后对每组数据执行上述贪心策略...
5. **函数与递归**:函数是代码的复用单元,而递归则是函数调用自身的一种方法,常用于解决复杂问题,如树的遍历、斐波那契数列等。 6. **结构体与类**:C++支持面向对象编程,结构体和类是封装数据和方法的工具。...
1. 线段树类的定义,可能包含成员变量(如数组存储线段树节点的值)和构造函数。 2. 区间查询方法,接收区间的起始和结束位置,返回该区间的特定信息(如最值或和)。 3. 区间更新方法,接收更新的位置和新的值,...
1. **基础语法**:包括变量声明、类型转换、运算符优先级、流程控制(if-else、switch-case、for、while、do-while)、函数定义与调用、返回值等。 2. **数据结构**:涉及基本的数据结构如数组、链表、栈、队列,...
- 可能会使用递归函数来实现自顶向下的动态规划,但为了效率,通常会用一个记忆化搜索的数组来存储中间结果,避免重复计算。 解题报告的DOC文档则会详细解释以上步骤,包括如何理解问题、为什么选择动态规划、如何...
2. 定义函数`DP(i, j)`,表示当前位置`(i, j)`的最大滑行距离。如果`cnt[i][j]`已经有值,则直接返回,否则进行计算。 3. 对于当前点`(i, j)`,检查其上下左右四个相邻点。如果相邻点的高度更低,那么以该相邻点为...