• SDNU 1508.F.Feed the monkey(DFS)


    Description

    Alice has a monkey, she must feed fruit to the monkey every day.She has three kinds of fruits, bananas, 
    peaches and apples. Every day, she chooses one in three, and pick one of this to feed the monkey. 
    But the monkey is picky, it doesn’t want bananas for more than D1 consecutive days, peaches for more than D2 
    consecutive days, or apples for more than D3 consecutive days. Now Alice has N1 bananas, N2 peaches and N3 
    apples, please help her calculate the number of schemes to feed the monkey.

    Input

     Multiple test cases. The first line contains an integer T (T<=20), indicating the number of test case.
    Each test case is a line containing 6 integers N1, N2, N3, D1, D2, D3 (N1, N2, N3, D1, D2, D3<=50).

    Output

     One line per case. The number of schemes to feed the monkey during (N1+N2+N3) days.
    The answer is too large so you should mod 1000000007.

    Sample Input

    1
    2 1 1 1 1 1
    

    Sample Output

    6

    Hint

     Answers are BPBA, BPAB, BABP, BAPB, PBAB, and ABPB(B-banana P-peach A-apple)

    思路:这是一道思维题,要求的是排列组合问题。解题方式是:一个一个的添加水果,尝试在末尾位置添加不同的水果,看有多少种不同的排列方式。特别要注意的是,这道题对空间有限制,所以定义数组不能太大,否则会MLE。

    ///
    ///                            _ooOoo_
    ///                           o8888888o
    ///                           88" . "88
    ///                           (| -_- |)
    ///                           O  =  /O
    ///                        ____/`---'\____
    ///                      .'  \|     |//  `.
    ///                     /  \|||  :  |||//  
    ///                    /  _||||| -:- |||||-  
    ///                    |   | \  -  /// |   |
    ///                    | \_|  ''---/''  |   |
    ///                      .-\__  `-`  ___/-. /
    ///                  ___`. .'  /--.--  `. . __
    ///               ."" '<  `.___\_<|>_/___.'  >'"".
    ///              | | :  `- \`.;` _ /`;.`/ - ` : | |
    ///                 `-.   \_ __ /__ _/   .-` /  /
    ///         ======`-.____`-.___\_____/___.-`____.-'======
    ///                            `=---='
    ///        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ///                      Buddha Bless, No Bug !
    ///
    
    #include <bits/stdc++.h>
    using namespace std;
    
    const int mod = 1000000007;
    const int maxn = 55;
    
    int T, n[3], d[3], dp[maxn][maxn][maxn][3][maxn], sum;
    int dfs(int n1, int n2, int n3, int t, int m)
    {
        if(n1 > n[0] || n2 > n[1] || n3 > n[2] || (n1 + n2 + n3) > sum) return 0;///如果某一种水果的数量已经超过了已有的数量
        if(dp[n1][n2][n3][t][m] != -1) return dp[n1][n2][n3][t][m];///如果dp[n1][n2][n3][t][m]是已经计算过的
        if(t == 0 && m > d[0] || t == 1 && m > d[1] || t == 2 && m > d[2]) return 0;///如果连续的水果已经超过规定的连续天数
        if(n1 + n2 + n3 == sum) return 1;
        int ans = 0;
        ///尝试在水果队列后面加水果,计算排列方式的数量
        if(t == 0)
        {
            ans = (ans + dfs(n1 + 1, n2, n3, 0, m + 1)) % mod;///如果在队列后面加苹果,会有多少种排列方式
            ans = (ans + dfs(n1, n2 + 1, n3, 1, 1)) % mod;///如果在队列后面加香蕉,会有多少种排列方式
            ans = (ans + dfs(n1, n2, n3 + 1, 2, 1)) % mod;///如果在队列后面加桃子,会有多少种排列方式
            return dp[n1][n2][n3][t][m] = ans;
        }
        if(t == 1)
        {
            ans = (ans + dfs(n1 + 1, n2, n3, 0, 1)) % mod;///如果在队列后面加苹果,会有多少种排列方式
            ans = (ans + dfs(n1, n2 + 1, n3, 1, m + 1)) % mod;///如果在队列后面加香蕉,会有多少种排列方式
            ans = (ans + dfs(n1, n2, n3 + 1, 2, 1)) % mod;///如果在队列后面加桃子,会有多少种排列方式
            return dp[n1][n2][n3][t][m] = ans;
        }
         if(t == 2)
        {
            ans = (ans + dfs(n1 + 1, n2, n3, 0, 1)) % mod;///如果在队列后面加苹果,会有多少种排列方式
            ans = (ans + dfs(n1, n2 + 1, n3, 1, 1)) % mod;///如果在队列后面加香蕉,会有多少种排列方式
            ans = (ans + dfs(n1, n2, n3 + 1, 2, m + 1)) % mod;///如果在队列后面加桃子,会有多少种排列方式
            return dp[n1][n2][n3][t][m] = ans;
        }
    }
    
    int main()
    {
        scanf("%d", &T);
        while(T--)
        {
            int ans = 0;
            scanf("%d%d%d%d%d%d", &n[0], &n[1], &n[2], &d[0], &d[1], &d[2]);
            sum = n[0] + n[1] + n[2];
            memset(dp, -1, sizeof(dp));
            ans = (ans + dfs(1, 0, 0, 0, 1)) % mod;
            ans = (ans + dfs(0, 1, 0, 1, 1)) % mod;
            ans = (ans + dfs(0, 0, 1, 2, 1)) % mod;
            printf("%d
    ", ans);
        }
        return 0;
    }

     

     

     
  • 相关阅读:
    基础练习 分解质因数
    基础练习 矩阵乘法
    基础练习 矩形面积交
    基础练习 完美的代价
    设计模式完结(7)--桥接模式----处理多维度变化
    设计模式完结(6)--适配器模式----不兼容结构的协调
    设计模式完结(5)-建造者模式
    设计模式完结(4)-原型模式
    设计模式完结(3)单例模式
    设计模式读完总结(2)工厂模式
  • 原文地址:https://www.cnblogs.com/RootVount/p/11236732.html
Copyright © 2020-2023  润新知