李白打酒加强版
问题描述
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒显,从家里出来,酒显中有酒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;
}