UvaLive6441(期望概率dp)
1.涉及负数时同时维护最大和最小,互相转移。
2.考场上最大最小混搭转移WA,赛后发现如果是小的搭小的,大的搭大的就可过,类似这种:
db a = (C[i] - W[i]) * dp1[i - 1][j - 1] - (1 - C[i] - W[i]) * dp1[i - 1][j - 1]; db b = (C[i] - W[i]) * dp2[i - 1][j - 1] - (1 - C[i] - W[i]) * dp2[i - 1][j - 1];
于是猜测原因的话可能是:最大和最小的不一定是同一种方案,而P1、P2、P3这三种情况转移到现态必须是同一种方案转移过来?
1 const int maxn = 2e3 + 5; 2 int n, m, T; 3 db dp1[maxn][maxn], dp2[maxn][maxn], C[maxn], W[maxn]; 4 5 int main() { 6 scanf("%d", &T); 7 for (int kase = 1; kase <= T; kase++) { 8 scanf("%d %d", &n, &m); 9 rep(i, 1, n) { 10 scanf("%lf", &C[i]); 11 C[i] /= 100; 12 } 13 rep(i, 1, n) { 14 scanf("%lf", &W[i]); 15 W[i] /= 100; 16 } 17 init(dp1, 0); 18 init(dp2, 0); 19 dp1[0][0] = dp2[0][0] = 15000; 20 for (int i = 1; i <= n; i++) { 21 for (int j = 0; j <= m; j++) { 22 if (j > i) break; 23 dp1[i][j] = 15001, dp2[i][j] = -15001; 24 if (j < i) { 25 db a = (1 - 2.0*W[i]) * dp1[i - 1][j]; 26 db b = (1 - 2.0*W[i]) * dp2[i - 1][j]; 27 dp1[i][j] = min(a, b); 28 dp2[i][j] = max(a, b); 29 } 30 if (j) { 31 db a = (C[i] - W[i]) * dp1[i - 1][j - 1] - (1 - C[i] - W[i]) * dp1[i - 1][j - 1]; 32 db b = (C[i] - W[i]) * dp2[i - 1][j - 1] - (1 - C[i] - W[i]) * dp2[i - 1][j - 1]; 33 dp1[i][j] = min(dp1[i][j], min(a, b)); 34 dp2[i][j] = max(dp2[i][j], max(a, b)); 35 } 36 } 37 } 38 db ans = 15001; 39 for (int j = 0; j <= m; j++) ans = min(ans, dp1[n][j]); 40 printf("Case #%d: %.3lf\n", kase, ans); 41 } 42 return 0; 43 }