1 条题解
-
0
自动搬运
来自洛谷,原作者为

Xy_top
constructive thinking搬运于
2025-08-24 22:42:28,当前版本为作者最后更新于2022-12-03 17:09:32,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
看到都是顺次转移的动态规划,我来写一个贡献转移。
设 为当前走到第 个位置,看了 次花,有 斗酒的方案数。
题目中说了初始两斗酒,那么 。
重点是怎么前推后,依次循环 ,,,
如果 不是 ,那么我们在第 个位置看花或者经过酒店。
看花:走到第 个位置,看了 次花,酒的数量变为 。
酒馆:走到第 个位置,看了 次花,酒的数量变为 。
状态转移方程:
if (f[i][j][k] != 0)//这里也可以简写成 if(f[i][j][k]) { f[i + 1][j + 1][k - 1] += f[i][j][k]; f[i + 1][j][k * 2] += f[i][j][k]; }注意! 只需要循环到 ,不需要循环到 ,如果循环到了 :
首先,再看花变成 已经对答案没有任何的贡献了。
其次,这样还会多算。如果不看花只能是没有酒,一直经过酒店,
但是题目要求最后一次只能经过花,所以不行。
还有一个问题:酒的斗数上线是什么?
显然不会超过 ,不然最后的酒就喝不完了,所以也循环到 。
代码:
#include <iostream> using namespace std; int n, m; int f[205][105][105]; int main() { cin >> n >> m; f[0][0][2] = 1; for (int i = 0; i < n + m; i ++) for (int j = 0; j < m; j ++) for (int k = 0; k <= m; k ++) if (f[i][j][k]) { if (k > 0) f[i + 1][j + 1][k - 1] = (f[i + 1][j + 1][k - 1] + f[i][j][k]) % 1000000007; if (k <= 50) f[i + 1][j][k * 2] = (f[i + 1][j][k * 2] + f[i][j][k]) % 1000000007; } cout << f[n + m][m][0]; return 0; }
- 1
信息
- ID
- 7964
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者