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;
    }

     

     

     
  • 相关阅读:
    CORS跨域解决方案
    修改数据库排序规则实践总结
    【转】通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core?
    调用远程数据库的T-SQL和SP(SQLSERVER)
    解决在微信网页中百度地图定位不准确的问题
    VUE小知识点
    实现鼠标移过时,显示图片的功能
    实现导出功能
    两数据库表之间迁移插入数据
    IIS配置FTP
  • 原文地址:https://www.cnblogs.com/RootVount/p/11236732.html
Copyright © 2011-2022 走看看