Kleofáš and the n-thlon

我们可以用dp算出比当前这个人得分少的概率, 然后人数乘概率就好啦。

dp[ i ][ j ]表示进行了 i 轮 得分为 j 的概率, 因为每个人都是独立地这样算是可以的, 然后前缀和优化一下。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long
using namespace std;

const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;

int n, m, all, x[N];
double dp[2][N], sum[N];

int main() {
    scanf("%d%d", &n, &m);
    if(m == 1) return puts("1.000000000000"), 0;
    double f = 1.0 / (m - 1);
    for(int i = 1; i <= n; i++) scanf("%d", &x[i]), all += x[i];
    int cur = 0, lst = 1;
    dp[cur][0] = sum[0] = 1;
    for(int i = 1; i <= n; i++) {
        swap(cur, lst);
        for(int j = i; j <= i * m; j++) {
            int L = max(i - 1, j - m), R = min((i - 1) * m, j - 1);
            dp[cur][j] = f * sum[R];
            if(L > 1) dp[cur][j] -= f * sum[L - 1];
            if(j - x[i] >= L && j - x[i] <= R)
                dp[cur][j] -= f * dp[lst][j - x[i]];
        }
        sum[0] = 0;
        for(int j = 1; j <= i * m; j++) sum[j] = sum[j - 1] + dp[cur][j];
    }
    double ret = 0;
    for(int i = n; i < all; i++) ret += dp[cur][i];
    printf("%.12f\n", ret * (m - 1) + 1);
    return 0;
}

/*
*/