zoukankan      html  css  js  c++  java
  • POJ 1579 Function Run Fun【记忆化搜索】

    递归和打表找规律或者记忆化搜索

    题目链接:http://poj.org/problem?id=1579

    2012年暑假组队后第一场个人训练赛

    Function Run Fun

    Time Limit:1000MS

    Memory Limit:10000K

    Total Submissions:13148

    Accepted:6836

    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

    上午比赛的继续http://172.16.24.47:33/judge/contest/view.action?cid=5#problem/A

    我的思路,打表找规律。

    常规思路:

                       记忆化搜索(把计算的结果存在数组中,避免重复计算,从而避免超时)

    对于这些题目,还是常规思路的好

    我的代码:

    //AC 132k 16ms(by C++) POJ 1579
    
    #include<stdio.h>
    #include<math.h>
    
    int w(int a,int b,int c)
    {
    	if(a<=0 || b<=0 || c<=0)
    		return 1;
    	else if(a>20 || b>20 || c>20)
    		return 1048576;       //  只要有一个数大于20,则返回w(20,20,20)=1048576,即2的20次方
    	else if(b>=a || c>=a)     //只要后面两个数有一个大于a,则返回2的a次方(开始超时后,打表得出的规律。。。)
    		return (double)pow((double)2,a);     //注意pow函数的强制类型转换,一不小心就编译错误了
    	else if(a<b && b<c)
    		return w(a,b,c-1)+w(a,b-1,c)-w(a,b-1,c);
    	else
    		return  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()
    {
    	int a,b,c;
    	double ans;
    	while(scanf("%d%d%d",&a,&b,&c)!=EOF)
    	{
    		if(a==-1 && b==-1 && c==-1)
    			break;
    		else
    		{
    			printf("w(%d, %d, %d) = ",a,b,c);
    			ans=w(a,b,c);
    		}
    		printf("%.0lf\n",ans);
    	}
    	return 0;
    }


    我同学的常规思路的代码:

    //叶
    //思路:运用递归会超时,故而只要计算出前w[i][j][k](0<=k<=20&&0<=i<=20&&0<=j<=20) 
    
    #include<stdio.h>
    #include<iostream>
    using namespace std;
    int w[21][21][21];
    
    void build()
    {
    	int i,j,k;
    	for(i=0;i<=20;i++)
    		for(j=0;j<=20;j++)
    			for(k=0;k<=20;k++)
    			{
    				if(i<=0 || j<=0 || k<=0)
    					w[i][j][k]=1;
    				else if(i<j && j<k)
    					w[i][j][k]=w[i][j][k-1]+w[i][j-1][k-1]-w[i][j-1][k];
    				else
    					w[i][j][k]=w[i-1][j][k]+w[i-1][j-1][k]+w[i-1][j][k-1]-w[i-1][j-1][k-1] ;
    			}
    }
    
    int main()
    {
        build();
    	int a,b,c,s;
    	while(scanf("%d%d%d",&a,&b,&c)!=EOF && !(a==-1 && b==-1 && c==-1))
    	{   
    		if(a<=0||b<=0|c<=0)
    			s=1;
    		else if(a>20||b>20||c>20)
    			s=w[20][20][20];
    		else
    			s=w[a][b][c];                                                     
    		printf("w(%d, %d, %d) = %d\n",a,b,c,s);
    	}
    	return 0;
    }
    


  • 相关阅读:
    Running APP 使用说明
    Android 控件八 WebView 控件
    Android 控件七 ImageView 控件
    Android 控件六 CheckBox 控件
    Android 控件五 RadioButton 控件
    Android 控件四 EditText 控件
    Android 控件三 TextView 控件实现 Button
    Android 控件二 Button
    Android 基础控件演示实例
    Android 控件一 TextView
  • 原文地址:https://www.cnblogs.com/freezhan/p/3219106.html
Copyright © 2011-2022 走看看