#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <set>
using namespace std;
#define N 220
#define ls (i << 1)
#define rs (ls | 1)
#define md (ll + rr >> 1)
#define lson ll, md, ls
#define rson md + 1, rr, rs
#define LL long long
#define inf 0x3f3f3f3f
int n, k;
int p[N];
double dp[N][N][N];
int calc(int a, int b, int c, int d, int z) {
int l = z - b, r = z - a;
l = max(l, c);
r = min(r, d);
if(l <= r) return r - l + 1;
return 0;
}
int C(int x) {
return x * (x + 1) / 2;
}
int main() {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; ++i) scanf("%d", &p[i]);
for(int i = 1; i <= n; ++i) {
for(int j = i + 1; j <= n; ++j) dp[0][i][j] = 0;
}
double tot = C(n);
for(int m = 1; m <= k; ++m) {
for(int x = 1; x <= n; ++x) {
for(int y = x + 1; y <= n; ++y) {
double &u = dp[x][y][m];
u = 0;
double s = C(x - 1) + C(y - x - 1) + C(n - y);
u += s / tot * dp[x][y][m-1];
for(int t = 1; t < y; ++t) {
u += calc(1, x, x, y - 1, t + x) / tot * dp[t][y][m-1];
}
for(int t = 1; t + y - x <= n; ++t) {
u += calc(1, x, y, n, t + y) / tot * (1 - dp[t][t+y-x][m-1]);
}
for(int t = x + 1; t <= n; ++t) {
u += calc(x + 1, y, y, n, y + t) / tot * dp[x][t][m-1];
}
}
}
}
double ans = 0;
for(int i = 1; i <= n; ++i) {
for(int j = i + 1; j <= n; ++j) {
if(p[i] < p[j]) ans += dp[i][j][k];
else ans += 1 - dp[i][j][k];
}
}
printf("%.12lf\n", ans);
return 0;
}
Codeforces 513G2 Inversions problem (dp)
最新推荐文章于 2020-04-09 10:57:47 发布