我们可以用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; } /* */