Test instructions: give you a sequence of n number, ask to find out the strict increment subsequence with M number, ask to find out how many different schemes
DP[I][J] Indicates the number of schemes with a strictly ascending subsequence length of J, ending with number I
Then the final answer should be Sigma (Dp[i][m]);
Obviously: dp[i][j] = Sigma (dp[k][j-1]); of which 1 <= K < I and A[k] < a[i];
How to solve the problem of strict increment of the topic requirement?
hdu4719 This problem is also dealt with, that is, we only need from small to large DP on the line.
But the complexity is O (n^3), obviously need to optimize, notice that should be from small to large DP, we have to do is to quickly find Sigma (Dp[k][j-1]) (not yet calculated to the DP value of 0) (note cannot directly use the array to maintain the prefix and)
Can be optimized with a tree-like array, with the final complexity O (N^2LOGN)
#include <bits/stdc++.h> #define LOWBIT (x) (x) & (-X) using namespace std;const int N = 1005;const int M = 1e9 + 7 ; int Dp[n][n], c[n][n];int a[n], r[n];bool cmp (int b, int c) {return a[b] < a[c];} void Update (int i, int j, int value) {while (I < N) {C[i][j] = c[i][j] + value% M; i + = Lowbit (i); }}int sum (int i, int j) {int s = 0; while (i > 0) {s = s + c[i][j]% M; I-= lowbit (i); } return s% M;} int main () {int n, m; int _, cas = 1; scanf ("%d", &_); while (_--) {scanf ("%d%d", &n, &m); for (int i = 1; I <= n; ++i) scanf ("%d", &a[i]); memset (c, 0, sizeof C); memset (DP, 0, sizeof DP); for (int i = 0; I <= N; ++i) r[i] = i; Sort (r + 1, r + N + 1, CMP); for (int i = 1; I <= n; ++i) {int id = r[i]; DP[ID][1] = 1; Update (ID, 1, 1); for (int j = 2; j <= m; ++j) {dp[id][j] = SUM (ID- 1, j-1); Update (ID, J, dp[id][j]); }} int ans = 0; for (int i = 1; I <= n; ++i) ans = ans + dp[i][m]% m; printf ("Case #%d:%d\n", cas++, ans% M); } return 0;}
CCPC_ Nanyang C The Battle of chibi DP + tree-like array