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. 把握linux内核设计思想(二):硬中断及中断处理

    [版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 操作系统负责管理硬件设备.为了使系统和硬件设备的协同工作不减少机器性能.系统和 ...

  2. c#线程顺序执行

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  3. 整合Kafka到Spark Streaming——代码示例和挑战

    作者Michael G. Noll是瑞士的一位工程师和研究员,效力于Verisign,是Verisign实验室的大规模数据分析基础设施(基础Hadoop)的技术主管.本文,Michael详细的演示了如 ...

  4. 【Python】selenium调用IE11浏览器,报错“找不到元素”NoSuchWindowException: Message:Unable to find element on closed window

    当编写自动化脚本,定位浏览器元素时,报如下错误: 代码: >>> # coding=utf-8 >>> from selenium import webdriver ...

  5. [Linux] 概念

    操作系统包括: 内核:管理硬件资源 库:没有执行入口的程序,用于提升软件开发效率 应用程序:有执行入口的程序 常见库文件: windows系统:dll(dynamic link library)动态链 ...

  6. 深入Asyncio(六)Tasks and Futures

    Tasks and Futures 大多数的工作只涉及到Task.create_task()方法,就像前面代码一样,Future是Task的父类,提供与loop交互的所有功能. Future对象表示某 ...

  7. JAVA程序开发按位运算的记录

    忘记在哪里看到一个面试题:把int a,b的值互换,不能使用临时变量.刚开始完全懵逼,脑子里面全是浆糊,不知道如何下手.查看答案后猛地一惊,心想居然还有这种操作,真是叹为观止,真的感觉自己的基础是如此 ...

  8. linux环境tomcat配置及hadoop 2.6伪分布模式安装配置

    一.ubuntu 15.04.openjdk1.7.tomcat7环境配置 1. 配置openjdk1.7,输入命令: -jdk 2. 查看java是否安装成功,输入命令: envjava -vers ...

  9. 用Newtonsoft将json串转为对象的方法(详解)

    首先,将json串转为一个JObject对象: JObject jo = (JObject)JsonConvert.DeserializeObject(CurrentSelectedItemReq) ...

  10. c# 根据读取的配置信息删除某个目录及下所有文件

    #region 定时删除目录文件 /// <summary> /// 定时删除目录文件 /// northeasttycoon /// </summary> /// <p ...