• AcWing 232. 守卫者的挑战


    题目链接

    大型补档计划。

    比较显然的dp

    (f[i][j][k]) 为前 (i) 次,擂台上了 (j) 次,空闲容量(背包 - 使用的)为 (k) 的概率。

    • 不上擂台的转移:(f[i + 1][j][k] += f[i][j][k] * (1 - p[i]) / 100)

    • 上擂台: (f[i + 1][j + 1][k + a[i]] += f[i][j][k] * p[i] / 100)

    看似容量是 (2000),实际上我们需要的不超过 (400),所以可以压缩,不需要的取 (min) 就行。

    时间复杂度 (O(n ^ 3))

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    const int N = 205, S = 405, P = 200;
    int n, L, K, a[N];
    double p[N], f[N][S], g[N][S];
    int main() {
    	scanf("%d%d%d", &n, &L, &K);
    	K = min(K, n);
    	f[0][P + K] = 1;
    	for (int i = 1; i <= n; i++) scanf("%lf", p + i);
    	for (int i = 1; i <= n; i++) {
    	    scanf("%d", a + i);
    	    if (a[i] >= 0) K += a[i];
    	}
    	K = min(K, n);
    	for (int i = 1; i <= n; i++) {
    		memcpy(g, f, sizeof g);
    		memset(f, 0, sizeof g);
    		for (int j = 0; j <= n; j++) {
    		    for (int k = P - n; k <= P + K; k++) {
    		        if (!g[j][k]) continue;
    		        f[j][k] += g[j][k] * (100 - p[i]) / 100;
    		        if (k + a[i] >= 0) {
    		            f[j + 1][min(P + K, k + a[i])] += g[j][k] * p[i] / 100;
    		        }
    		    }
    		}
    	}
    
    	double ans = 0;
    	for (int i = L; i <= n; i++)
    		for (int j = P; j <= P + K; j++) ans += f[i][j];
    	printf("%.6lf", ans);
    	return 0;
    }
    
  • 相关阅读:
    第四章 JavaScript面向对象
    第二章 JavaScript操作DOM2
    第三章 JavaScript操作DOM
    第二章 JavaScript操作BOM2
    第二章 JavaScript操作BOM
    第一章 JavaScript基础
    java面向对象总结1
    java面向对象总结
    第七章 用表组织数据
    2020.10.22
  • 原文地址:https://www.cnblogs.com/dmoransky/p/12380307.html
Copyright © 2020-2023  润新知