李白打酒--蓝桥杯(dp)

该博客探讨了一道关于李白在路上遇到花和酒店饮酒问题的动态规划解决方案。题目描述李白在遇到花时会喝掉一斗酒,遇到酒店时酒量翻倍,最终酒要喝完且最后一次遇到的是花。通过状态转移方程`dp[i][j][k]`表示还需遇到i次花,j次店,酒壶中有k斗酒的情况,博主给出了完整的C++代码实现,求出了所有可能的顺序方案数。

题意:

李白有一天拿着酒壶出来玩,酒壶里装着2斗酒,在路上他会碰到花和酒店,碰到花的话他会喝1斗酒,碰到酒店的话他会将他的酒的斗数变为两倍。

在一路上李白共遇到店n次,花m次,且已知李白最后一次碰到的是花,酒正好喝完了。

问你李白这一路遇到店和花的顺序,有多少种不同的可能。

思路:

状态表示:dp[i][j][k]表示还要遇到i次花,j次店,此时酒壶里有k斗酒能让最后一次碰到的是花,且酒正好喝完的合法方案数。

状态转移:dp[i][j][k]状态可通过两个状态转移而来,一个是dp[i-1][j][k-1],即下一次碰到的是花,对应酒的斗数为当前值减1,另一个是dp[i][j-1][k*2],即下一次他碰到的是酒店,酒的斗数是当前的两倍。

初始状态:很明显,能确定唯一方案数的状态为dp[i][0][i],当途中不经过酒店时,方案数只有1种(一直碰到的是花),dp[0][0][k](k>0)dp[0][j][k](j>0,k\geq 0)是不合法的方案,因为最后酒不能有剩余且最后一次碰到的一定是花。i\geqslant 1时的其他的状态通过转移方程得到。

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int MOD=1e9+7;
const int N=105;
ll dp[N][N][N*2];
/*
i剩花的次数 j剩店的次数 k当前酒壶中酒的斗数 
*/
int n,m;
int main(){
	cin>>n>>m;
	for(int i=0;i<=m;i++){
		dp[i][0][i]=1;
	}
	for(int i=1;i<=m;i++)
		for(int j=1;j<=n;j++)
			for(int k=i;k>=0;k--)
			//k从i开始枚举,若k大于i,合法方案数肯定是0,因为最后一次碰到花酒肯定喝不完 
				dp[i][j][k]=(dp[i-1][j][k-1]+dp[i][j-1][k*2])%MOD;
	
	printf("%lld\n",dp[m][n][2]);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值