P8786 李白打酒加强版 题解
李白打酒加强版
题目大意
一开始酒显里有
这一路上一共遇到店
计算这一路上遇到店和花的顺序总共有多少种可能(答案模
允许
思路
这题我一眼就看出是一个动态规划题 (因为看了标签)。
由于最后一次固定为遇到花,所以可以先把
- 状态:
dp[i][j][k]
表示来到第 处地点,遇到店 次,酒显里还有 斗酒的方案数。 - 转移方程:
- 遇到店:
dp[i - 1][j - 1][k / 2]
转移到dp[i][j][k]
(需保证 并且 为偶数) - 遇到花:
dp[i - 1][j][k + 1]
转移到dp[i][j][k]
。
- 遇到店:
- 初始状态:
dp[0][0][2] = 1
- 目标状态:
dp[n + m][n][1]
很显然,如果直接连续一百次遇到店(酒显里还有酒时),酒显里的酒的斗数就会变得很大。
但是,要想喝最多
Code
点击查看代码
#include <iostream> using namespace std; const int mod = 1e9 + 7; int n, m; int dp[210][110][110]; // 注意数组大小 int main(){ cin >> n >> m; m--, dp[0][0][2] = 1; // 初始状态 for (int i = 1; i <= n + m; i++){ // 一共 n + m 处地点 for (int j = 0; j <= min(n, i); j++){ // 最多只能遇店 n 次,但是也不能超过 i 次 for (int k = 0; k <= 100; k++){ // 100 以上不用考虑 dp[i][j][k] = dp[i - 1][j][k + 1]; // 遇到花 if (k % 2 == 0 && j){ // 满足要求,可以遇到店 dp[i][j][k] = (dp[i][j][k] + dp[i - 1][j - 1][k / 2]) % mod; // 状态转移方程,记得取模 } } } } cout << dp[n + m][n][1]; // 输出目标状态 return 0; }
本文作者:wnsyou の blog
本文链接:https://www.cnblogs.com/wnsyou-blog/p/17410214.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步