codeforces 626D 概率DP

codeforces 626D


题意:

给 定 含 有 n 个 小 球 的 袋 子 , 第 i 个 小 球 的 点 数 为 a i , 袋 中 任 意 两 个 小 球 点 数 不 同 。 给定含有n个小球的袋子,第i个小球的点数为a_i,袋中任意两个小球点数不同。 niai
甲 乙 轮 流 从 袋 中 摸 球 , 一 共 进 行 三 局 , 每 局 结 束 后 小 球 被 放 回 袋 中 。 甲乙轮流从袋中摸球,一共进行三局,每局结束后小球被放回袋中。
每 局 结 束 后 小 球 点 数 总 和 大 的 一 方 获 胜 。 每局结束后小球点数总和大的一方获胜。
问 第 一 、 二 局 甲 获 胜 , 第 三 局 乙 获 胜 的 概 率 。 问第一、二局甲获胜,第三局乙获胜的概率。


题解:

p [ i ] 表 示 单 局 获 胜 且 点 数 差 为 i 的 概 率 , 枚 举 1 — n , 每 一 种 可 能 性 为 1 C n 2 。 p[i]表示单局获胜且点数差为i的概率,枚举1—n,每一种可能性为\frac 1{C_n^2}。 p[i]i1nCn21
d p [ j ] 表 示 第 一 、 二 局 甲 获 胜 且 点 数 和 为 j 的 概 率 , 第 三 局 乙 获 胜 的 必 要 条 件 为 j ≤ 5000 。 dp[j]表示第一、二局甲获胜且点数和为j的概率,第三局乙获胜的必要条件为j≤5000。 dp[j]jj5000

  • i + j ≤ 5000 时 , d p [ i + j ] + = p [ i ] ∗ p [ j ] i+j≤5000时,dp[i+j]+=p[i]*p[j] i+j5000dp[i+j]+=p[i]p[j]

#include 
using namespace std;
const int N = 5001;
int a[N];
double p[N];
double dp[N];

int main() {
    int n;
    cin >> n;
    for(int i = 1 ; i <= n ; i++){
        cin >> a[i];
    }
    sort(a+1, a+1+n);
    for(int i = 1 ; i <= n ; i++){
        for(int j = 1 ; j < i ; j++){
            p[a[i]-a[j]] += 1.0/(n*(n-1)/2);
        }
    }
    for(int i = 1 ; i <= 5000 ; i++){
        for(int j = 1 ; j <= 5000 ; j++){
            if(i+j <= 5000){
                dp[i+j] += p[i]*p[j];
            }
        }
    }
    double ans = 0;
    for(int i = 1 ; i <= 5000 ; i++){
        for(int j = 1 ; j < i ; j++){
            ans += p[i]*dp[j];
        }
    }
    cout << setiosflags(ios::fixed) << setprecision(10) << ans << endl;
    return 0;
}

你可能感兴趣的:(概率DP)