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

幸存者
当生命意识到宇宙奥秘的存在时,距它最终解开这个奥秘只有一步之遥了。搬运于
2025-08-24 22:38:21,当前版本为作者最后更新于2022-05-17 12:56:59,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
思路
一看到这题,就想到了 dp 的做法。
我们令 表示从 到 共有 次 , 次 且满足题目条件的不同的数列的个数。
考虑每次 或 ,不难列出状态转移方程 。但需要考虑一种特殊情况,当 时(即 ),需要令 。
但是这样空间复杂度是 的,所以需要使用滚动数组,将第一维整体模 即可。
注意:若 ,则只有一种可能的序列,直接判断数列 是否符合要求即可。
#include <bits/stdc++.h> using namespace std; int dp[2][10010]; const int mod = 1e9 + 7; int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); int t; cin >> t; while (t--) { int n, p, x, y, ans = 0; cin >> n >> p >> x >> y; if (x == y) { bool flag = false; for (int i = 1; i <= n; i++) if (1ll * i * x % p == 0) { flag = true; break; } cout << (flag ? 0 : 1) << endl; continue; } dp[0][0] = 1; for (int i = 0; i <= n; i++) for (int j = 0; i + j <= n; j++) { if (i == 0 && j == 0) continue; if ((1ll * i * x + 1ll * j * y) % p != 0) { if (i == 0) dp[i & 1][j] = dp[i & 1][j - 1]; else if (j == 0) dp[i & 1][j] = dp[i & 1 ^ 1][j]; else dp[i & 1][j] = (dp[i & 1 ^ 1][j] + dp[i & 1][j - 1]) % mod; } else dp[i & 1][j] = 0; if (i + j == n) ans = (ans + dp[i & 1][j]) % mod; } cout << ans << endl; } return 0; }
- 1
信息
- ID
- 7605
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者