• 【浮*光】#概率dp# 洛谷p2059 卡牌游戏


    很有意思的概率dp问题...因为有相对性在里面,所以转移方法很巧妙。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    #include <stack>
    #include <queue>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    
    /*【p2059】卡牌游戏 
    类似约瑟夫游戏,求每个玩家获胜的概率。*/
    
    //【标签】概率dp + 状态设计 + 数学分析(相对性)
    
    //f[i][j]表示还剩i个人时、当前相对庄家位置为j的人最终获胜、的概率。f[1][1]=1。
    //枚举庄家抽到的牌k,即此时被淘汰的人的相对位置为c。下一局i-1个人,更新庄家。
    //即:当c>j时,第j个人是新庄家之后的第i−c+j个人;当c<j时,第j个人-->第j−c个人。
    //转移方程:f[i][j]=f[i][j]+f[i−1][i−c+j]÷m,c>j;f[i][j]=f[i][j]+f[i−1][j−c]÷m,c<j。 
    
    void reads(int &x){
        int fx=1;x=0;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')fx=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s-'0');s=getchar();}
        x=x*fx;//正负号
    }
    
    int n,m,a[10019]; double f[1019][1019]; 
    
    int main(){
        reads(n),reads(m); for(int i=1;i<=m;i++) reads(a[i]);
        f[1][1]=1; for(int i=2;i<=n;i++)
            for(int j=1;j<=i;j++) for(int k=1;k<=m;k++){
                int c=(a[k]%i==0)?i:(a[k]%i); //牌k,数字c
                //↑↑即a[k]%i,c为此局被淘汰的人的相对位置
                if(c>j) f[i][j]=f[i][j]+f[i-1][i-c+j]/m;
                if(c<j) f[i][j]=f[i][j]+f[i-1][j-c]/m;
        } for(int i=1;i<=n;i++) printf("%.2lf%% ",f[n][i]*100.0);
    } //注意%的符号输出形式:在printf中要写成%% ↑↑

                                 ——时间划过风的轨迹,那个少年,还在等你

  • 相关阅读:
    JavaScript笔记三两个
    形式参数分别是基本类型和引用类型的调用
    if (strAreaCode.Find("体检")>=0)
    C++编写DLL文件
    error LNK2001: unresolved external symbol __imp__closesocket@4
    accept函数
    socket编程
    MFC控件使用大全
    DLL导出函数
    LINK : fatal error LNK1104: cannot open file的解决方法
  • 原文地址:https://www.cnblogs.com/FloraLOVERyuuji/p/10396476.html
Copyright © 2020-2023  润新知