李白打酒加强版本

2.李白打酒加强版 - 蓝桥云课

李白打酒加强版

问题描述

话说大诗人李白,一生好饮。幸好他从不开车。

一天,他提着酒显,从家里出来,酒显中有酒2斗。他边走边唱:

| 无事街上走,提显去打酒。逢店加一倍,遇花喝一斗。 |

这一路上,他一共遇到店N次,遇到花M次。已知最后一次遇到的是花,他正好把酒喝光了。

请你计算李白这一路遇到店和花的顺序,有多少种不同的可能?

注意:显里没酒(0斗)时遇店是合法的,加倍后还是没酒;但是没酒时遇花是不合法的。

输入格式

第一行包含两个整数N和M。

输出格式

输出一个整数表示答案。由于答案可能很大,输出模1000000007的结果。

样例输入

5 10

样例输出

14

样例说明

如果我们用 0 代表遇到花,1 代表遇到店,14 种顺序如下:

010101101000000

010110010010000

011000110010000

100010110010000

011001000110000

100011000110000

100100010110000

010110100000100

011001001000100

100011001000100

100100011000100

011010000010100

100100100010100

101000001010100

评测用例规模与约定

对于 40%40% 的评测用例: 1≤N,M≤10 。

对于 100%100% 的评测用例: 1≤N,M≤100。

思路:

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const ll maxn = 105; // 根据题目M的最大值100调整数组维度
ll N, M;
ll mem[maxn][105][105]; // 调整后的数组维度
ll dfs(ll sv, ll store, ll flower) 
{
    if (sv < 0 || store > N || flower > M) 
	return 0;
    if (sv > (M - flower)) 
	return 0; // 剪枝条件,当前酒量超过剩余花次数
    if (mem[sv][store][flower] != -1) 
	return mem[sv][store][flower];
    if (store == N && flower == M - 1 && sv == 1) 
	{
        return mem[sv][store][flower] = 1;
    }
    ll sum = 0;
    // 尝试遇到店
    if (store < N) 
	{
        sum = (sum + dfs(sv * 2, store + 1, flower)) % mod;
    }
    // 尝试遇到花,且当前酒量必须大于0
    if (sv > 0 && flower < M) 
	{
        sum = (sum + dfs(sv - 1, store, flower + 1)) % mod;
    }
    return mem[sv][store][flower] = sum;
}

int main() 
{
    cin >> N >> M;
    memset(mem, -1, sizeof(mem));
    ll ans = dfs(2, 0, 0) % mod;
    cout << ans;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod =  1000000007 ;
ll mem[205][205][205];
ll N,M;
ll dfs(ll sv,ll store,ll flower)
{
	ll sum = 0;
	if(mem[sv][store][flower] != -1)
	return mem[sv][store][flower];
	if(sv < 0 || store < 0 || flower < 0)
	return 0;
  if(sv > flower)
  return 0;
	if(sv == 1 && store == 0 && flower == 1)
	return mem[sv][store][flower] = 1;
	//遇到店
	if(store - 1 >= 0)
	sum = (sum + dfs(sv*2,store-1,flower))%mod;
	//遇到花 
	if(sv > 0 && flower - 1 >= 0)
	sum = (sum + dfs(sv-1,store,flower-1))%mod;
	mem[sv][store][flower] = sum;
	return sum;
	
}
int main() 
{
	cin >> N >> M;
	memset(mem,-1,sizeof(mem));
	cout << dfs(2,N,M);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值