POJ 1579-Function Run Fun(记忆化搜索-递归)

来源:互联网 发布:广东网络电视营业厅 编辑:程序博客网 时间:2024/05/18 12:32
Function Run Fun
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 18930 Accepted: 9612

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: 


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 12 2 210 4 650 50 50-1 7 18-1 -1 -1

Sample Output

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

Source

Pacific Northwest 1999

题目意思:

给出a,b,c,按以下递归方式计算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)

解题思路:

直接递归必然超时,所以一定要记忆化搜索。
用dp[a][b][c]记录w(a,b,c)的值,每次判断一下如果计算过就不再重复计算,注意防止下标越界的问题,要先处理负数再处理大数。

#include <iostream>#include <cstdio>#include <cstring>#include <bitset>#include <map>#include <iomanip>#include <algorithm>#define MAXN 21#define INF 0xfffffffusing namespace std;/*if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns:1if 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)*/int dp[MAXN][MAXN][MAXN];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 dp[20][20][20]=w(20,20,20);//为了防止下标越界(大于20)所以先处理    if(dp[a][b][c]!=0) return dp[a][b][c];//已经计算过的不再重复计算    if(a<b&&b<c)  return dp[a][b][c]=(w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c));    return dp[a][b][c]=(w(a-1,b,c)+w(a-1,b-1,c)+w(a-1, b, c-1)-w(a-1,b-1,c-1));}int main(){#ifdef ONLINE_JUDGE#else    freopen("G:/cbx/read.txt","r",stdin);    //freopen("G:/cbx/out.txt","w",stdout);#endif    ios::sync_with_stdio(false);    cin.tie(0);    memset(dp,0,sizeof(dp));    int a,b,c;    while(cin>>a>>b>>c)    {        if(a==-1&&b==-1&&c==-1) break;        cout<<"w("<<a<<", "<<b<<", "<<c<<") = "<<w(a,b,c)<<endl;    }    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 京东商家发错货怎么办 京东自营发错货怎么办 手机店中奖手机怎么办 支付宝账户挂失怎么办 微信被骗1800怎么办 存储卡无法格式化怎么办 内存卡硬件损坏怎么办 苹果换新手机id怎么办 支付宝存在风险怎么办 键盘玩游戏失灵怎么办 机械键盘按键冲突怎么办 想和他和好怎么办 异地恋吵架了怎么办 异地恋吵架后怎么办 横屏游戏变竖屏怎么办 三星w2016购买后怎么办 电脑账户删不了怎么办 手机副版出问题怎么办 越狱证书过期了怎么办 iphone7不停重启怎么办 手机被病毒入侵怎么办 苹果手机不息屏怎么办 苹果手机散屏怎么办 苹果手机屏幕死机了怎么办 苹果手机屏死机怎么办 微信号账号异常怎么办 手机设置加密了怎么办 华为手机触屏坏了怎么办 安卓启动器停止怎么办 手机显示停止运行怎么办 手机来电被拦截怎么办 手机被加黑名单怎么办 手机短信被屏蔽了怎么办 手机信息被拦截怎么办 手机有感染病毒怎么办 华为p10速度慢怎么办 华为手机清理慢 怎么办 华为手机有回音怎么办 手机没有返回键怎么办 手机总显示内存不足怎么办 扩音器耳麦接触不良怎么办