zoukankan      html  css  js  c++  java
  • 【题解】JLOI2013卡牌游戏

      这题最开始是用 (n^{4})的算法水过的,之后才想出的(n^{3})正解。首先,(n^{4}) 应该是很容易想到的:设状态 (f[i][j][k]) 为有 (i) 个人,庄家为 (j) 号人时,第 (k) 个人胜出的概率。这样,只需要去掉本轮淘汰的人,加上 (i - 1) 个人时该人胜出的概率即可。

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 55
    #define db double
    int n, m, a[maxn];
    db P, f[maxn][maxn][maxn];
    
    int read()
    {
        int x = 0, k = 1;
        char c;
        c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    int main()
    {
        n = read(), m = read();
        P = (db) 1 / (db) m;
        for(int i = 1; i <= m; i ++) a[i] = read();
        f[1][1][1] = 1;
        for(int i = 2; i <= n; i ++)
            for(int j = 1; j <= i; j ++)
                for(int k = 1; k <= i; k ++)
                {
                    for(int x = 1; x <= m; x ++)
                    {
                        int t = (a[x] + j - 1) % i, T = t + 1, K = k; 
                        if(!t) t = i; 
                        if(t == k) continue;
                        if(K > t) K -= 1; if(T > t) T -= 1;
                        f[i][j][k] += P * f[i - 1][T][K];
                    }
                }
        for(int i = 1; i <= n; i ++)
            printf("%.2lf%% ", f[n][1][i] * 100);
        return 0;
    }

       但是这题还有更优的做法。我们再看一看自己所设置的状态,详加思考就会发现:其实第二维是不必要的。谁做庄家实际上都是一个相对的概念,我们可以强制让(1) 号为庄家,这样只需要在新的环上找出原来编号为 (k) 的人对应的新编号 (k') 并加上其概率就好啦。

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 55
    #define db double
    int n, m, a[maxn];
    db P, f[maxn][maxn];
    
    int read()
    {
        int x = 0, k = 1;
        char c;
        c = getchar();
        while(c < '0' || c > '9') { if(c == '-') k = -1; c = getchar(); }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * k;
    }
    
    int main()
    {
        n = read(), m = read();
        P = (db) 1 / (db) m;
        for(int i = 1; i <= m; i ++) a[i] = read();
        f[1][1] = 1;
        for(int i = 2; i <= n; i ++)
            for(int k = 1; k <= i; k ++)
                for(int x = 1; x <= m; x ++)
                {
                    int t = a[x] % i, T = t + 1, K = k; 
                    if(!t) t = i; 
                    if(t == k) continue;
                    if(K > t) K -= 1; if(T > t) T -= 1;
                    if(K < T) K = (i - T + K);
                    else if(K > T) K = K - T + 1;
                    else K = 1;
                    f[i][k] += P * f[i - 1][K];
                }
        for(int i = 1; i <= n; i ++)
            printf("%.2lf%% ", f[n][i] * 100);
        return 0;
    }
  • 相关阅读:
    C#基础知识简单梳理
    knearest neighbor
    二叉查找树的实现
    Unix/Linux 那些系统启动后的进程
    Nginx反向代理IIS
    线程漫谈——线程同步之信号量和互斥量
    BtxCMS@B.T.X 项目及界面展示 [下载]
    MVC in MFC or WTL
    HTTP HTTPS WebService
    ASP.NET WebAPI RC 竟然不支持最常用的json传参
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/9090745.html
Copyright © 2011-2022 走看看