一直在考虑, 每一段的贡献, 没想到这个东西能直接dp。。因为所有的h都是一样的。
#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 = 2000 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); int n, h, x[N], lft[N], rgt[N]; double ans, p, pr, pl; double f[N][N][2][2]; bool vis[N][N][2][2]; double dp(int i, int j, int u, int v) { if(i > j) return 0; if(vis[i][j][u][v]) return f[i][j][u][v]; double& ans = f[i][j][u][v]; double tmp1 = 0, tmp2 = 0; if(!u) ans += 0.5 * pl * (dp(i + 1, j, 0, v) + min(h, x[i] - x[i - 1])), tmp1 = min(h, x[i] - x[i - 1]); else ans += 0.5 * pl * (dp(i + 1, j, 0, v) + min(h, x[i] - x[i - 1] - h)), tmp1 = min(h, x[i] - x[i - 1] - h); if(v) ans += 0.5 * pr * (dp(i, j - 1, u, 1) + min(h, x[j + 1] - x[j])), tmp2 = min(h, x[j + 1] - x[j]); else ans += 0.5 * pr * (dp(i, j - 1, u, 1) + min(h, x[j + 1] - h - x[j])), tmp2 = min(h, x[j + 1] - h - x[j]); int L = min(rgt[i], j), R = max(lft[j], i); ans += 0.5 * pr * (dp(L + 1, j, 1, v) + x[L] - x[i] + (L != j ? h : tmp2)); ans += 0.5 * pl * (dp(i, R - 1, u, 0) + x[j] - x[R] + (R != i ? h : tmp1)); vis[i][j][u][v] = true; return ans; } int main() { scanf("%d%d%lf", &n, &h, &p); pl = p, pr = 1 - p; for(int i = 1; i <= n; i++) scanf("%d", &x[i]); x[0] = -inf, x[n + 1] = inf; sort(x + 1, x + 1 + n); lft[1] = 1, rgt[n] = n; for(int i = 2; i <= n; i++) lft[i] = x[i] - h < x[i - 1] ? lft[i - 1] : i; for(int i = n - 1; i >= 1; i--) rgt[i] = x[i] + h > x[i + 1] ? rgt[i + 1] : i; printf("%.10f ", dp(1, n, 0, 1)); return 0; } /* */