以下是b2b电子商务网站廊坊seo网站管理
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;}// 尝试遇到花,且当前酒量必须大于0if (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;
}