问题描述
话说大诗人李白, 一生好饮。幸好他从不开车。
一天, 他提着酒显, 从家里出来, 酒显中有酒 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 。
运行限制
- 最大运行时间:1s
- 最大运行内存: 256M
思路,dp[i][j][k]表示到第i个地方经过了j个花,壶里有k 点酒的情况数量
没注意要求最后一个必须是花,调了十好几分钟
n,m=map(int,input().split())
mod=1000000007
dp=[[[0 for i in range(m+1)]for ii in range(m+1)]for ii in range(n+m+1)]
dp[0][0][2]=1 #初始化 没出发壶里有2点酒的可能为1种情况
for i in range(1,n+1+m):
for j in range(min(i+1,m+1)): #注意条件
for k in range(m-j+1): #如果酒的数量比剩下的花还多,那肯定不行,喝不完啊
if (k==0 and j!=m):continue #壶里没酒了花还没看完也不行
if (k==m): #注意推导式含k+1 不特判会越界
if (k%2==0):
dp[i][j][k]=dp[i-1][j][k//2]
continue
if (k%2): #酒数为奇数 上一个地点只能是花
dp[i][j][k]=dp[i-1][j-1][k+1]
if (k%2==0):
dp[i][j][k]=(dp[i-1][j-1][k+1]+dp[i-1][j][k//2])%mod
"""for i in range(1,n+1+m):
for j in range(m+1):
print(i,j,dp[i][j])"""
print(dp[n+m-1][m-1][1]) #题目要求