[Cometoj#3 C]子序列子序列子序列..._动态规划_数论
子序列子序列子序列...
题目链接:https://cometoj.com/contest/38/problem/C?problem_id=1542
数据范围:略。
题解:
神仙题,感觉这个题比$D$还难一些,$Orz$原题解。
http://static.eduzhixin.com/cometoj/solution/contest_38_1.pdf
代码:
#include <bits/stdc++.h> #define N 5010 #define M 21 #define Pyd 1000000007 using namespace std; int a[N]; int dp[M][N]; int tmp[N]; int mod[M]; int n, m; char *p1, *p2, buf[100000]; #define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ ) int rd() { int x = 0, f = 1; char c = nc(); while (c < 48) { if (c == '-') f = -1; c = nc(); } while (c > 47) { x = (((x << 2) + x) << 1) + (c ^ 48), c = nc(); } return x * f; } int main() { n = rd(), m = rd(); for (int i = 1; i <= n; i ++ ) { a[i] = rd(); } int k = 0; while (m % (1 << k) == 0) k ++ ; mod[0] = mod[1] = m; for (int i = 2; i <= k; i ++ ) mod[i] = mod[i - 1] / 2; dp[0][0] = 1; for (int i = 1; i <= n; i ++ ) { for (int j = 0; j < mod[k]; j ++ ) tmp[(j + a[i]) % mod[k]] = dp[k][j]; for (int j = 0; j < mod[k]; j ++ ) { dp[k][j] += tmp[j]; if (dp[k][j] >= Pyd) dp[k][j] -= Pyd; } for (int p = k - 1; p > 0; p -- ) { for (int j = 0; j < mod[p]; j ++ ) { int nj = (j + a[i]) % mod[p + 1]; dp[p + 1][nj] += dp[p][j]; if (dp[p + 1][nj] >= Pyd) dp[p + 1][nj] -= Pyd; } } dp[1][a[i]] ++ ; if (dp[1][a[i]] >= Pyd) dp[1][a[i]] -= Pyd; } int ans = 0; for (int i = 1; i <= k; i ++ ) { ans += dp[i][0]; if (ans >= Pyd) ans -= Pyd; } cout << ans << endl ; return 0; }
| 欢迎来原网站坐坐! >原文链接<