zoukankan      html  css  js  c++  java
  • ACM学习历程——HDU1331 Function Run Fun(锻炼多维dp的打表)

    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
    ", w(a, b, c));
        }
        return 0;
    }
    
     
     
  • 相关阅读:
    【leetcode】1295. Find Numbers with Even Number of Digits
    【leetcode】427. Construct Quad Tree
    【leetcode】1240. Tiling a Rectangle with the Fewest Squares
    【leetcode】1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold
    【leetcode】1291. Sequential Digits
    【leetcode】1290. Convert Binary Number in a Linked List to Integer
    【leetcode】1269. Number of Ways to Stay in the Same Place After Some Steps
    【leetcode】1289. Minimum Falling Path Sum II
    【leetcode】1288. Remove Covered Intervals
    【leetcode】1287. Element Appearing More Than 25% In Sorted Array
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4111449.html
Copyright © 2011-2022 走看看