One Person Game ZOJ-3329 期望DP

One Person Game
在这里插入图片描述

solution

d p [ i ] = ∑ k = 1 k 1 + k 2 + k 3 d p [ i + k ] p [ k ] + d p [ 0 ] p [ 0 ] + 1 dp[i]=\sum\limits_{k=1}^{k1+k2+k3}dp[i+k]p[k]+dp[0]p[0]+1 dp[i]=k=1k1+k2+k3dp[i+k]p[k]+dp[0]p[0]+1

d p [ i ] = A [ i ] d p [ 0 ] + B [ i ] dp[i]=A[i]dp[0]+B[i] dp[i]=A[i]dp[0]+B[i]

d p [ i ] = ∑ k = 1 k 1 + k 2 + k 3 ( A [ i + k ] d p [ 0 ] + B [ i + k ] ) p [ k ] + d p [ 0 ] p [ 0 ] + 1 dp[i]=\sum\limits_{k=1}^{k1+k2+k3}(A[i+k]dp[0]+B[i+k])p[k]+dp[0]p[0]+1 dp[i]=k=1k1+k2+k3(A[i+k]dp[0]+B[i+k])p[k]+dp[0]p[0]+1

= ( ∑ k = 1 k 1 + k 2 + k 3 A [ i + k ] p [ k ] + p [ 0 ] ) d p [ 0 ] + ( ∑ k = 1 k 1 + k 2 + k 3 B [ i + k ] p [ k ] + 1 ) =(\sum\limits_{k=1}^{k1+k2+k3}A[i+k]p[k]+p[0])dp[0]+(\sum\limits_{k=1}^{k1+k2+k3}B[i+k]p[k]+1) =(k=1k1+k2+k3A[i+k]p[k]+p[0])dp[0]+(k=1k1+k2+k3B[i+k]p[k]+1)

A [ i ] = ∑ k = 1 k 1 + k 2 + k 3 A [ i + k ] p [ k ] + p [ 0 ] , B [ i ] = ∑ k = 1 k 1 + k 2 + k 3 B [ i + k ] p [ k ] + 1 A[i]=\sum\limits_{k=1}^{k1+k2+k3}A[i+k]p[k]+p[0],B[i]=\sum\limits_{k=1}^{k1+k2+k3}B[i+k]p[k]+1 A[i]=k=1k1+k2+k3A[i+k]p[k]+p[0]B[i]=k=1k1+k2+k3B[i+k]p[k]+1

d p [ 0 ] = B [ i ] 1 − A [ 0 ] dp[0]=\frac{B[i]}{1-A[0]} dp[0]=1A[0]B[i]

code

/*SiberianSquirrel*/
/*CuteKiloFish*/
#include <bits/stdc++.h>
using namespace std;

int a, b, c, k1, k2, k3;
long double p[2510];
long double A[2510], B[2510];

void solve() {
    int n, _; cin >> _;
    while(_ --) {
        cin >> n >> k1 >> k2 >> k3;
        cin >> a >> b >> c;
        memset(p, 0, sizeof p);
        for(int i = 1; i <= k1; ++ i) {
            for(int j = 1; j <= k2; ++ j) {
                for(int k = 1; k <= k3; ++ k) {
                    if(i != a || j != b || k != c)
                        p[i + j + k] += 1.0 / k1 / k2 / k3;
                }
            }
        }
        memset(A, 0, sizeof A);
        memset(B, 0, sizeof B);
        for(int i = n; i >= 0; -- i) {
            A[i] = 1.0 / k1 / k2 / k3; B[i] = 1;
            for(int j = 1; j <= k1 + k2 + k3; ++ j) {
                A[i] += A[i + j] * p[j];
                B[i] += B[i + j] * p[j];
            }
        }
        cout << fixed << setprecision(15) << B[0] / (1 - A[0]) << endl;
    }

}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("input", "r", stdin);
    freopen("output", "w", stdout);
    signed test_index_for_debug = 1;
    char acm_local_for_debug = 0;
    do {
        if (acm_local_for_debug == '$') exit(0);
        if (test_index_for_debug > 20)
            throw runtime_error("Check the stdin!!!");
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    } while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
    solve();
#endif
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值