zoukankan      html  css  js  c++  java
  • BZOJ3191: [JLOI2013]卡牌游戏

    3191: [JLOI2013]卡牌游戏

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 642  Solved: 433
    [Submit][Status][Discuss]

    Description

     
    N个人坐成一圈玩游戏。一开始我们把所有玩家按顺时针从1到N编号。首先第一回合是玩家1作为庄家。每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先把卡片上的数字向所有玩家展示,然后按顺时针从庄家位置数第X个人将被处决即退出游戏。然后卡片将会被放回卡牌堆里并重新洗牌。被处决的人按顺时针的下一个人将会作为下一轮的庄家。那么经过N-1轮后最后只会剩下一个人,即为本次游戏的胜者。现在你预先知道了总共有M张卡片,也知道每张卡片上的数字。现在你需要确定每个玩家胜出的概率。
    这里有一个简单的例子:
    例如一共有4个玩家,有四张卡片分别写着3,4,5,6.
    第一回合,庄家是玩家1,假设他选择了一张写着数字5的卡片。那么按顺时针数1,2,3,4,1,最后玩家1被踢出游戏。
    第二回合,庄家就是玩家1的下一个人,即玩家2.假设玩家2这次选择了一张数字6,那么2,3,4,2,3,4,玩家4被踢出游戏。
    第三回合,玩家2再一次成为庄家。如果这一次玩家2再次选了6,则玩家3被踢出游戏,最后的胜者就是玩家2.
     

    Input

    第一行包括两个整数N,M分别表示玩家个数和卡牌总数。
    接下来一行是包含M个整数,分别给出每张卡片上写的数字。
     

    Output

    输出一行包含N个百分比形式给出的实数,四舍五入到两位小数。分别给出从玩家1到玩家N的胜出概率,每个概率之间用空格隔开,最后不要有空格。
     

    Sample Input

    5 5
    2 3 5 7 11

    Sample Output

    22.72% 17.12% 15.36% 25.44% 19.36%

    输入样例2:
    4 4
    3 4 5 6

    HINT

    对于100%的数据,有1<=N<=50 1<=M<=50 1<=每张卡片上的数字<=50

    思路{

      简单的$DP$

      设$dp[i][j]$表示圈的大小为$i$的情况下,$j$号人胜利的概率。

      每次删除一个人相当于递归子问题,判断一下当前删除的是否是$j$。

      那么有转移方程:

      $dp[i][j]=dfrac{sum_{k=1}^{cnt}dp[i-1][(j-a[k]+n)\%n]}{cnt}$

      记忆化搜索即可。

    }

    #include<bits/stdc++.h>
    #define db double
    #define LL long long
    #define RG register
    #define il inline
    #define N 100
    using namespace std;
    db dp[N][N];bool vis[N][N];
    int a[N],cnt;
    void print(db ans){
      printf("%.2lf",ans*100);
      cout<<"%";
    }
    db dfs(int n,int m){
      if(vis[n][m])return dp[n][m];
      vis[n][m]=1;db &x=dp[n][m];
      if(n==1)return x=1;
      for(int i=1;i<=cnt;++i)
        if(((a[i]-1)%n)!=m){
          int temp=m-a[i];while(temp<0)temp+=n;
          temp%=n;
          x+=dfs(n-1,temp);
        }
      x/=cnt;
      return x;
    }
    int main(){
      int n;
      scanf("%d%d",&n,&cnt);
      for(int i=1;i<=cnt;++i)scanf("%d",a+i);
      for(int i=0;i<n;++i){
        print(dfs(n,i));
        if(i!=n-1)cout<<" ";
      }
      return 0;
    }
    
  • 相关阅读:
    AcWing 1135. 新年好 图论 枚举
    uva 10196 将军 模拟
    LeetCode 120. 三角形最小路径和 dp
    LeetCode 350. 两个数组的交集 II 哈希
    LeetCode 174. 地下城游戏 dp
    LeetCode 面试题 16.11.. 跳水板 模拟
    LeetCode 112. 路径总和 递归 树的遍历
    AcWing 1129. 热浪 spfa
    Thymeleaf Javascript 取值
    Thymeleaf Javascript 取值
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7784802.html
Copyright © 2011-2022 走看看