zoukankan      html  css  js  c++  java
  • 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;
    }

     

     

     
  • 相关阅读:
    input搜索框实时检索功能实现(超简单,核心原理请看思路即可)
    django blank 和autonow
    dwebsocket的坑
    vue 动态添加active+父子传值
    NO 2,人生苦短,我学python之python+selenium元素定位
    NO 1,人生苦短,我学python之python+selenium自动化环境搭建
    SPU与SKU概念
    数据库,缓存数据一致性常用解决方案总结
    利用注解 + 反射消除重复代码
    Nacos学习与实战
  • 原文地址:https://www.cnblogs.com/RootVount/p/11236732.html
Copyright © 2011-2022 走看看