小猴吃水果

有一个小猴子,饲养员要喂她吃水果,现在有3 种水果, 如果长时间吃一种水果小猴子很容易吃吐, 所以,饲养员要保证每种水果不能连续超过 d1 d2 d3 天 给你每种食物初始的份数, 每天吃一份,问吃完所有食物有多少种不同的组合呢?
思路:记忆化搜索,dp[num1][num2][num3][pre][con],num1num2 num3表示三种水果剩余数,pre表示上一个放的
是哪个水果,con表示上一个水果已经连续放了多少天。
#include<iostream>  
#include<cstdio>  
#include<cstring>  
using namespace std;  
const int maxn = 55;  
const int mod = 1e9+7;  
int dp[maxn][maxn][maxn][3][maxn];  
int n1, n2, n3, d1, d2, d3;  
  
int dfs(int num1, int num2, int num3, int pre, int con)  
{  
    if(num1 < 0 || num2 < 0 || num3 < 0) return 0;  
    if((pre==0&&con>d1) || (pre==1&&con>d2) || (pre==2&&con>d3)) return 0;  
    if(!num1 && !num2 && !num3) return 1;  
    if(dp[num1][num2][num3][pre][con] != -1) return dp[num1][num2][num3][pre][con];  
    int ans = 0;  
    if(pre == 0)  
    {  
        ans = (ans+dfs(num1-1, num2, num3, 0, con+1))%mod;  
        ans = (ans+dfs(num1, num2-1, num3, 1, 1))%mod;  
        ans = (ans+dfs(num1, num2, num3-1, 2, 1))%mod;  
    }  
    else if(pre == 1)  
    {  
        ans = (ans+dfs(num1-1, num2, num3, 0, 1))%mod;  
        ans = (ans+dfs(num1, num2-1, num3, 1, con+1))%mod;  
        ans = (ans+dfs(num1, num2, num3-1, 2, 1))%mod;  
    }  
    else  
    {  
        ans = (ans+dfs(num1-1, num2, num3, 0, 1))%mod;  
        ans = (ans+dfs(num1, num2-1, num3, 1, 1))%mod;  
        ans = (ans+dfs(num1, num2, num3-1, 2, con+1))%mod;  
    }  
    return dp[num1][num2][num3][pre][con] = ans;  
}  
  
int main(void)  
{  
    int t;  
    cin >> t;  
    while(t--)  
    {  
        memset(dp, -1, sizeof(dp));  
        scanf("%d%d%d%d%d%d", &n1, &n2, &n3, &d1, &d2, &d3);  
        int ans = 0;  
        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, 1))%mod;  
        printf("%d\n", ans);  
    }  
    return 0;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值