zoukankan      html  css  js  c++  java
  • hdu1579 Function Run Fun(深搜+记忆化)

    版权声明:本文为博主原创文章。未经博主同意不得转载。vasttian https://blog.csdn.net/u012860063/article/details/37076755

    转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents

    题目链接:http://acm.hdu.edu.cn/showproblem.php?

    pid=1579


    Problem 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


    一个典型的自底向上的记忆化搜索问题。地道的DP问题,虽说非常easy,可是确实是太经典了,
    题目所给的本身就是一个递归式,可是假设直接用递归做肯定会超时。


    解决的方法就是用记忆化搜索,以空间换时间,将已计算好的结果存到数组里以备后用。复杂度O(n^3).

    代码一例如以下:

    #include <cstdio>
    #include <cstring>
    int dp[57][57][57];
    int dfs(int a, int b, int c)
    {
    	if(a<=0 || b<=0 || c<=0)
    		return 1;
    	if(a>20 || b>20 || c>20)
    		return dfs(20,20,20);
    	if(dp[a][b][c])
    		return dp[a][b][c];
    	if(a < b && b < c)
    		dp[a][b][c]=dfs(a,b,c-1)+dfs(a,b-1,c-1)-dfs(a,b-1,c);
    	else
    		dp[a][b][c]=dfs(a-1,b,c)+dfs(a-1,b-1,c)+dfs(a-1,b,c-1)-dfs(a-1,b-1,c-1);
    	return dp[a][b][c];
    }
    int main()
    {
    	int a, b, c;
    	while(~scanf("%d%d%d",&a,&b,&c))
    	{
    		if(a == -1 && b == -1 && c == -1)
    			break;
    		int ans = dfs(a,b,c);
    		printf("w(%d, %d, %d) = %d
    ",a,b,c,ans);
    	}
    	return 0;
    }

    代码二例如以下:

    #include <cstdio>
    #define N 20
    int a,b,c,w[N+1][N+1][N+1];
    int dp(int a,int b,int c)
    {
        int i,j,k;
    	
        if (a<=0 || b<=0 || c<=0)
            return 1;
        if (a>20 || b>20 || c>20)
            a=b=c=20;
        for (i=0;i<=N;i++)
            for (j=0;j<=N;j++)
                w[0][i][j]=w[i][0][j]=w[i][j][0]=1;
    		for (i=1;i<=a;i++)
    			for (j=1;j<=b;j++)
    				for (k=1;k<=c;k++)
    					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];
    					return w[a][b][c];
    }
    
    int main()
    {
        while (~scanf("%d %d %d",&a,&b,&c))
    	{
    		if(a == -1 && b == -1 && c == -1)
    			break;
    		int ans = dp(a,b,c);
            printf("w(%d, %d, %d) = %d
    ",a,b,c,ans);
    	}
        return 0;
    }


  • 相关阅读:
    一种高压侧母线过流检测电路的实现
    编程逻辑之状态机学习
    STM32——驱动DS18B20
    迪文屏所有控件测试
    EC11使用原理简介以及LL库源码
    FreeRTOS API使用栗子
    常用官网链接
    CubeMX之FreeRTOS学习day02
    跟工程师学嵌入式开发:基于STM32和μC OS-Ⅲ(学习笔记)
    CubeMX之FreeRTOS学习day01
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10592093.html
Copyright © 2011-2022 走看看