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
 
 
递推的式子是直接给出来的。里面最关键的两个式子是:
f[i][j][k] = f[i][j][k-1] + f[i][j-1][k-1] - f[i][j-1][k];
以及
f[i][j][k] = f[i-1][j][k] + f[i-1][j-1][k] + f[i-1][j][k-1] - f[i-1][j-1][k-1];
可知这个三维dp式子,前一个式子都是在i那一维,通过特征观察可知,是j一层一层递推的(或者k)。
而第二个式子又可以看出是i一层层的递推。
故递推的时候只需要三个for循环就搞定。
但是还需要注意的是
任意i,j,f[i][j][0] = f[i][0][j] = f[0][i][j] = 1;
这个条件给每一维的0这个面都赋成了1,有了这个初始化,就可以放心地递推了。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <string>
#define inf 0x3fffffff
#define eps 1e-10 using namespace std; int f[25][25][25]; void Init()
{
for (int i = 0; i <= 20; i++)
for (int j = 0; j <= 20; j++)
f[i][j][0] = f[i][0][j] = f[0][i][j] = 1;
for (int i = 1; i <= 20; i++)
for (int j = 1; j <= 20; j++)
for (int k = 1; k <= 20; k++)
{
if (i < j && j < k)
f[i][j][k] = f[i][j][k-1] + f[i][j-1][k-1] - f[i][j-1][k];
else
f[i][j][k] = f[i-1][j][k] + f[i-1][j-1][k] + f[i-1][j][k-1] - f[i-1][j-1][k-1];
}
} int w(int a, int b, int c)
{
if (a <= 0 || b <= 0 || c <= 0)
return 1;
if (a > 20 || b > 20 || c > 20)
return f[20][20][20];
return f[a][b][c];
} int main()
{
//freopen("test.txt", "r", stdin);
Init();
int a, b, c;
while (scanf("%d%d%d", &a, &b, &c) != EOF)
{
if (a == -1 && b == -1 && c == -1)
break;
printf("w(%d, %d, %d) = ", a, b, c);
printf("%d\n", w(a, b, c));
}
return 0;
}
 
 

ACM学习历程——HDU1331 Function Run Fun(锻炼多维dp的打表)的更多相关文章

  1. ACM学习历程—CodeForces 176B Word Cut(字符串匹配 && dp && 递推)

    Description Let's consider one interesting word game. In this game you should transform one word int ...

  2. 完成了C++作业,本博客现在开始全面记录acm学习历程,真正的acm之路,现在开始

    以下以目前遇到题目开始记录,按发布时间排序 ACM之递推递归 ACM之数学题 拓扑排序 ACM之最短路径做题笔记与记录 STL学习笔记不(定期更新) 八皇后问题解题报告

  3. ACM学习历程—HDU 5512 Pagodas(数学)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5512 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是给了初始的集合{a, b},然后取集合里 ...

  4. ACM学习历程—HDU5521 Meeting(图论)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是一个人从1开始走,一个人从n开始走.让最 ...

  5. ACM学习历程—HDU2476 String painter(动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=2476 题目大意是给定一个起始串和一个目标串,然后每次可以将某一段区间染成一种字符,问从起始串到目标串最少需要染多 ...

  6. ACM学习历程—HDU5700 区间交(树状数组 && 前缀和 && 排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5700 这是这次百度之星初赛2B的第五题.省赛回来看了一下,有这样一个思路:对于所有的区间排序,按左值排序. 然后 ...

  7. ACM学习历程—HDU5701 中位数计数(中位数 && 计数排序)

    http://acm.hdu.edu.cn/showproblem.php?pid=5701 这是这次百度之星初赛2B的第六题.之前白山云做过类似的题,省赛完回来,我看了一下大概就有这样的思路:首先枚 ...

  8. ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=5696 这是这次百度之星初赛2B的第一题,但是由于正好打省赛,于是便错过了.加上2A的时候差了一题,当时有思路,但 ...

  9. ACM学习历程—HDU5668 Circle(数论)

    http://acm.hdu.edu.cn/showproblem.php?pid=5668 这题的话,假设每次报x个,那么可以模拟一遍, 假设第i个出局的是a[i],那么从第i-1个出局的人后,重新 ...

随机推荐

  1. POJ 1698 Alice&#39;s Chance(最大流+拆点)

    POJ 1698 Alice's Chance 题目链接 题意:拍n部电影.每部电影要在前w星期完毕,而且一周仅仅有一些天是能够拍的,每部电影有个须要的总时间,问能否拍完电影 思路:源点向每部电影连边 ...

  2. python之prettytable

    sdata={'语文':89,'数学':96,'音乐':39,'英语':78,'化学':88} #字典向Series转化 >>> studata=Series(sdata) > ...

  3. Android之怎样全屏显示

    三种方法: 1 自己定义主题(见设置自己定义样式和主题一节) http://blog.csdn.net/wei_chong_chong/article/details/47438907 2 使用系统自 ...

  4. iOS项目 -- 模仿花椒直播做的第二层界面完整版

    ,项目开始做了,好遗憾的是,花椒app有更新了版本,

  5. Python中文编码过程中遇到的一些问题

    首先,要明确encode()和decode()的差别 encode()的作用是将Unicode编码的字符串转换为其它编码格式. 比如:st1.encode("utf-8")  这句 ...

  6. python 基础 5.4 类的私有属性和私有方法

    一. 类的私有变量和私有方法 1>   在python 中可以通过在属性变量名前,加上双下划线定义属性为私有属性   2>特殊变量命名 a. _xx 以单下划线开头的表示的是protect ...

  7. Devexpress Spreadsheet 中文教程

    http://blog.csdn.net/hotmee/article/details/50554381

  8. slide.js

    define(['jquery'], function (jquery) { function buildSmooth(config, motivateCallBack) { var timer = ...

  9. 负载均衡,会话保持,session同步(转)

    一,什么负载均衡一个新网站是不要做负载均衡的,因为访问量不大,流量也不大,所以没有必要搞这些东西.但是随着网站访问量和流量的快速增长,单台服务器受自身硬件条件的限制,很难承受这么大的访问量.在这种情况 ...

  10. Git如何强制拉取一个远程分支到本地分支(转载)

    有时候,我们在使用git pull指令想把一个远程分支拉取到本地分支的时候,老是会拉取失败,这一般是因为某种原因,本地分支和远程分支的内容差异无法被git成功识别出来,所以git pull指令什么都不 ...