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

zxh_mc
DETERMINATION搬运于
2025-08-24 22:42:42,当前版本为作者最后更新于2022-11-25 20:10:21,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路比较简单的一道题。
用的五维 dp,看到二维和三维的 dp 直接膜了 orz。
正文开始。
分析
不难看出 dp。
因为 的值只与 有关,所以我们定义 被 满足为在这些 中最大的一项恰好为 。
用 来表示此状态下的方案数。
其中:
- 表示当前处于第 项。
- 表示当前这一项选择 。
- 表示 是否被 满足。
- 表示 是否被 满足。
- 表示 选择 。
显然, 的最大值就是 ,又因为 ,所以 的最大值也是 。
状态转移方程比较复杂。
如果 ,那么我们需要枚举 和 。
这时候存在两种情况:
- 被 满足,此时应该更新 的值。
- 不被 满足,此时应该更新 的值。
注意:在选择 的时候, 必须被 满足,原因显然。
但当 时,应该单独讨论,因为 的选择会影响到 dp 数组的第 项,而 则不会。思路跟 的情况类似,不再赘述。
最后统计答案时,我们有几种情况:
- ,因为此时 和 已经被满足,而其它的 也都被满足,直接加上即可。
- 当 时可以相加,因为 数组是环形的。
- 当 时可以相加,原因同上。
最后,记得取模。
AC Code
臭长臭长的代码 qwq。#include <bits/stdc++.h> using namespace std; const int N = 1010; const int MOD = 1e9 + 7; int n; int dp[N][11][2][2][11], b[N], am[N]; int st; inline int nxt (int idx) { return ((idx + 1) % n); } inline int pre (int idx) { return ((idx - 1 + n) % n); } int m (int x) { if (x < MOD) return x; return x - MOD; } int main () { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin >> n; for (int i = 0;i < n;i++) cin >> b[i]; for (int i = 0;i < n;i++) am[i] = min(b[pre(i)], min(b[i], b[nxt(i)])); for (int i = 0;i <= am[0];i++) if (i < b[0]) dp[0][i][0][0][i] = 1; else dp[0][i][1][1][i] = 1; for (int x = 0;x <= am[0];x++) for (int st = 0;st <= 1;st++) for (int j = 0;j <= am[1];j++) { if (j < b[1] && x < b[1]) { if (j < b[0]) dp[1][j][0][st][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][0][st][x] = m(dp[1][j][0][st][x]); else dp[1][j][0][1][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][0][1][x] = m(dp[1][j][0][1][x]); } else { if (j < b[0]) dp[1][j][1][st][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][1][st][x] = m(dp[1][j][1][st][x]); else dp[1][j][1][1][x] += m(dp[0][x][0][st][x] + dp[0][x][1][st][x]), dp[1][j][1][1][x] = m(dp[1][j][1][1][x]); } } for (int i = 2;i < n;i++) { int p = i - 1; for (int x = 0;x <= am[0];x++) for (int st = 0;st <= 1;st++) { for (int j = 0;j <= am[i];j++) { for (int z = 0;z <= am[p];z++) { if (j < b[i] && z < b[i]) { if (j < b[p]) dp[i][j][0][st][x] += dp[p][z][1][st][x];else dp[i][j][0][st][x] += m(dp[p][z][0][st][x] + dp[p][z][1][st][x]); dp[i][j][0][st][x] = m(dp[i][j][0][st][x]); } else { if (j < b[p]) dp[i][j][1][st][x] += dp[p][z][1][st][x]; else dp[i][j][1][st][x] += m(dp[p][z][0][st][x] + dp[p][z][1][st][x]); dp[i][j][1][st][x] = m(dp[i][j][1][st][x]); } } } } } int ans = 0; for (int x = 0;x <= am[0];x++) for (int i = 0;i <= am[n - 1];i++) { ans += dp[n - 1][i][1][1][x]; ans = m(ans); if (i >= b[0]) ans += dp[n - 1][i][1][0][x]; if (x >= b[n - 1]) ans += dp[n - 1][i][0][1][x]; ans = m(ans); } cout << ans << endl; return 0; }
- 1
信息
- ID
- 7987
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者