zoukankan      html  css  js  c++  java
  • 概率dp刷题

    CF717D Dexterina’s Lab

    • 题意:有一个 (n) 堆石子的 (nim) 游戏,石子数量从 (0)(x) 有一个概率 (p_i) ,代表了一堆石子数量为 (i) 的数量。求先手必赢的概率。
    • 题解:首先nim显然的是 (nim) 异或和为 (0) 是必输,然后可以构造 (A) 矩阵

    (A =egin{bmatrix} p[0 oplus 0 ] &p[0 oplus 1] & p[0 oplus 2]\ p[1 oplus 0 ] &p[1 oplus 1] & p[1 oplus 2]\ p[2 oplus 0 ] &p[2 oplus 1] & p[2 oplus 2] end{bmatrix})

    (ans) 矩阵就是 (ans = egin{bmatrix} dp[0] &0 & 0\ dp[1] &0 & 0\ dp[2] &0 & 0 end{bmatrix})
    (ans_{1, j}) 代表的意思是,在这一次,(dp[j]) ,即游戏出现他们异或和为(j) 情况的概率。

    • 代码:
    #include<bits/stdc++.h>
    #pragma comment(linker, "/STACK:102400000,102400000")
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    const ll N = 129;
    const ll inf = 0x3f3f3f3f;
    ld pp[N];
    const ll maxn = 10;
    struct Matrix {
       ld a[maxn][maxn];
       int n;
       Matrix (int sz, int kind) {
           this->n = sz;
           for (int i = 0; i < sz; i ++) {
               for (int j = 0; j < sz; j ++) {
                   a[i][j] = 0;
               }
           }
           for (int i = 0; i < sz; i ++) {
               a[i][i] = kind;
           }
       }
       Matrix operator*(Matrix rhs)const {
           Matrix ret(N - 1, 0);
           for (int i  = 0; i < n; i ++) {
               for (int j = 0; j < n; j ++) {
                   for (int k = 0; k < n; k ++) {
                       ret.a[i][j] += a[i][k] * rhs.a[k][j];
                   }
               }
           }
           return ret;
       }
       void out() {
           for (int i = 0; i < 5 ;i ++) {
               for (int j = 0; j < 5; j ++) {
                   cout << a[i][j] << " ";
               }
               cout << endl;
           }
       }
    } A(maxn - 1, 0);
    Matrix q_pow( int k) {
       Matrix ret = {N - 1, 1};
       Matrix x = A;
       while (k) {
           if (k & 1) {
               ret = ret * x;
           }
           k >>= 1;
           x = x * x;
       }
       return ret;
    }
    void solve() {
       int n, x;
       cin >> n >> x;
       for (int i = 0; i <= x; i ++) {
           cin >> pp[i];
       }
       cout << fixed<<setprecision(10);
       for (int i = 0; i <= N-2; i ++) {
           for (int j = 0; j <= N-2; j ++) {
               A.a[i][j] = pp[j ^ i];
               
           }
       }
       Matrix res = q_pow( n);
       Matrix d = Matrix(N - 1, 0);
       d.a[0][0] = 1;
       res = d * res;
       cout << 1.0-res.a[0][0] << endl;
    }
    signed main() {
    ll t = 1;//cin >> t;
    while (t--) {
       solve();
    }
    }
    
  • 相关阅读:
    c#多线程和Socket笔记
    Socket测试工具包的开发(TCP UDP)
    使用socket模拟服务器给客户端发消息
    AU3学习笔记
    c#委托与事件(三)
    c#委托与事件(二)
    使用的工具
    Zip 压缩问题件,获取真实扩展名
    PsExec使用
    socket 통신
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/15100776.html
Copyright © 2011-2022 走看看