题目描述
https://www.luogu.com.cn/problem/P2513
Solution
我们令 $f[i][j]$ 表示填了前 $i$ 个数,逆序对的个数为 $j$
当我们加入数 $i+1$ 时,能够产生的新逆序对的个数为 $0$ 到 $i$,注意到转移是一个区间,所以我们可以使用差分
时间复杂度为 $O(n^2)$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #define maxn 1010 using namespace std;
const int p = 10000;
int n, m;
int f[maxn][maxn];
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m; f[0][0] = 1; for (int i = 0; i < n; ++i) { for (int j = 0; j <= m; ++j) { if (!f[i][j]) continue; int l = j, r = min(m, j + i); f[i + 1][l] = (f[i + 1][l] + f[i][j]) % p; f[i + 1][r + 1] = (f[i + 1][r + 1] - f[i][j]) % p; } for (int j = 1; j <= m; ++j) f[i + 1][j] = (f[i + 1][j] + f[i + 1][j - 1]) % p; } cout << (f[n][m] + p) % p << "\n"; return 0; }
|