1. 程式人生 > 實用技巧 >端點星2020.12.2聯賽

端點星2020.12.2聯賽

T1

Solution

我們對於這 \(n\) 個數來進行討論

首先, 一共有 \(A_n^n\)中排列, 那麼分母我們就確定了

我們設 \(max_1\) 是最大的數, \(max_2\) 是第二大的數, \(max_3\) 是第三大的數... \(max_n\)是第n大的數

  1. 對於 \(max_1\) 它貢獻不管如何排列都為0
  2. 對於 \(max_2\) 它的貢獻是 \(max_1\)\(max_2\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\)
  3. 對於 \(max_3\) 它的貢獻是 \(max_2\)\(max_3\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\)
    + \(max_1\)\(max_3\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\)
  4. 對於 \(max_4\) 它的貢獻是 \(max_3\)\(max_4\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\) + \(max_2\)\(max_4\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\) + \(max_1\)\(max_4\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\)
    .
    .
    .
    n. 對於 \(max_n\) 它的貢獻是 \(max_{n - 1}\)\(max_n\)
    前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\) + \(max_{n - 2}\)\(max_n\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\) + ... + \(max_1\)\(max_n\) 前面的排列的個數 \(\dfrac{A_n^n}{A_2^2}\) 就是 \(\dfrac{A_n^n \times (n - 1)}{A_2^2}\)

以此類推, 那麼最終答案就是 : 所有的貢獻除以總共的排列數:

\(ans = \dfrac{\dfrac{A_n^n}{A_2^2} + \dfrac{A_n^n \times 2}{A_2^2} + \dfrac{A_n^n \times 3}{A_2^2} + ... + \dfrac{A_n^n \times (n - 1)}{A_2^2}}{A_n^n}\)

\(\Rightarrow ans = \dfrac{1}{A_2^2} + \dfrac{2}{A_2^2} + \dfrac{3}{A_2^2} + ... + \dfrac{(n - 1)}{A_2^2}\)

\(\Rightarrow ans = \dfrac{1}{2} + \dfrac{2}{2} + \dfrac{3}{2} + ... + \dfrac{(n - 1)}{2}\)

同時, 注意相同的數: 相同的數的貢獻取決於相同的第一的 \(max\)

即, 貢獻僅取決於大於他的數

Code :

/**
*  Author: Aliemo
*  Data: 
*  Problem: 
*  Time: O()
*/
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>

#define ll long long
#define rr register

#define inf 1e9
#define MAXN 100010

using namespace std;

inline int read() {
  int s = 0, f = 0;
  char ch = getchar();
  while (!isdigit(ch)) f |= ch == '-', ch = getchar();
  while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
  return f ? -s : s;
}

void print(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) print(x / 10);
  putchar(x % 10 + 48);
}

int T, n;

int a[MAXN];

double ans[MAXN];

inline bool cmp(int a, int b) {return a > b;}

signed main() {
  // freopen("calculation.in", "r", stdin);
  // freopen("calculation.out", "w", stdout);
  T = read();
  while (T--) {
    n = read();
    double res = 0, lazy = 0;
    for (rr int i = 1; i <= n; i++) a[i] = read();
    for (rr int i = 2; i <= n; i++) ans[i] = ans[i - 1] + 0.5;
    sort(a + 1, a + 1 + n, cmp);
    for (rr int i = 2; i <= n; i++) {
      if (a[i] != a[i + 1]) res += ans[i], lazy = ans[i];
      else res += lazy;
    }
    if (res == (double)((int)(res))) printf("%d", (int)(res));
    else printf("%.2f\n", res);
  }
}