zoukankan      html  css  js  c++  java
  • CodeForces

    题目

    (n) 堆石子,每堆石子的数量是 (i) 的概率是 (p_i)。两人轮流取石子,每次可以选任一堆取走任意数量的石子,但不能不取,不能取的人输,问在双方采取最佳策略的前提下先手必胜的概率。

    (nle 10^9),石子数量最大值满足在 ([1,100])

    解法

    首先我们知道 ( m Nim) 游戏的一个结论:当石子数异或和为 (0) 时先手必败。

    问题就转化成求异或和为零的概率,再用 (1) 减去这个概率就行了。

    我们令 (mathtt{dp[i][j]}) 为前 (i) 堆石子异或和为 (j) 的概率。

    那么就有:

    [mathtt{dp[i][j⊕k]=sum_{k=0}^{127}dp[i-1][k]*p[j]} ]

    我们用矩阵加速来加速。(mathtt{1e9}) 大约是 (mathtt{2^{27}}) 级别,又因为 (x) 的最大值为 (100),二进制有七位,而七位二进制最大的是 (127)。所以时间复杂度为 (mathtt{O(128^3*27)}) 可过(不过实际也没有这么大)。

    代码

    #include <cstdio>
    #include <cstring>
    
    const int lim = 128;
    
    int n, x;
    double t;
    struct Matrix {
        double a[lim][lim]; int n, m;
    
        Matrix() {memset(a, 0, sizeof a);}
    
        Matrix operator * (const Matrix &b) {
            Matrix r; r.n = n; r.m = b.m;
            for(int i = 0; i <= r.n; ++ i)
                for(int j = 0; j <= r.m; ++ j)
                    if(a[i][j])
                        for(int k = 0; k <= m; ++ k)
                            r.a[i][k] += a[i][j] * b.a[j][k];
            return r;
        }
    }per, ans;
    
    Matrix qkpow(int y) {
        Matrix ret; ret.n = ret.m = lim - 1;
        for(int i = 0; i <= ret.n; ++ i) ret.a[i][i] = 1;
        while(y) {
            if(y & 1) ret = ret * per;
            per = per * per; y >>= 1;
        }
        return ret;
    }
    
    int read() {
        int x = 0, f = 1; char s;
        while((s = getchar()) < '0' || s > '9') if(s == '-') f = -1;
        while(s >= '0' && s <= '9') {x = (x << 1) + (x << 3) + (s ^ 48); s = getchar();}
        return x * f;
    }
    
    void init() {
        per.n = per.m = lim - 1;
        for(int i = 0; i <= x; ++ i) {
            scanf("%lf", &t);
            for(int j = 0; j < lim; ++ j)
                per.a[j][i ^ j] = t;
        }
    }
    
    int main() {
        n = read(), x = read();
        init();
        ans = qkpow(n);
        printf("%.10f
    ", 1.0 - ans.a[0][0]);
        return 0;
    }
    
  • 相关阅读:
    windows 2008 64位在指定的 DSN 中,驱动程序和应用程序之间的体系结构不匹配
    uva 11552 dp
    A*搜索算法
    Dalvik虚拟机总结
    J2SE基础:5.面向对象的特性2
    Linux/Android——input_handler之evdev (四)【转】
    Linux/Android——input子系统核心 (三)【转】
    Linux/Android——输入子系统input_event传递 (二)【转】
    【Android】Android输入子系统【转】
    Linux/Android——usb触摸屏驱动
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/12660769.html
Copyright © 2011-2022 走看看