zoukankan      html  css  js  c++  java
  • [BZOJ 3191][JLOI 2013]卡牌游戏

    觉得这题很有必要讲一下!

    现在发现在做概率题,基本是向 dp 和 马尔可夫链 靠齐

    但是这一题真是把我坑了,因为状态太多,马式链什么的直接死了

    我一开始的想法就是用 f[i][j] 表示剩余 i 个人,现由 j 坐庄

    恩~ dp 方程还是老好想的嘛~

    wait! wait!! wait!!! 这尼马有后效性啊!有后效性啊!!

    然后想了半天毫无进展,一看题解……

    哎呦我 c 

    其实那个方程几乎对了,但!是!有后效性就要用重标号的方法去掉!

    怎么算去了呢?

    其实……谁是谁更本不重要!

    如果我们对每个人 i 都重标号为 0 ,列一次方程,那么每次都只算第 0 个人 (变为 0~n-1 个人) 存活的概率 即 f[1][0] 即可

    所有方程的区别只在边界条件不同而已,标号什么的完全不用管,也就没有后效性了!

    然后我们只要保证 0 不 over 即可,其他的都可以不用管了

    若这一轮的标号是 0~i , 然后第 j 个人 over 的话

    新标号为 0~i-1, 但是这里的 j~i-1 其实是原来的 j+1~i

    但是我们不用去管标号变了的问题,因为本质上是一样的

    f[i][(j+a[k]-1)%(i+1)]+=f[i+1][j]/M

    这么写就可以了,但是还有个问题:

    0 是不能被删的我们注意到在 f[i+1] -> f[i] 时

    f[i][0] 其实是 0 被删去后 1 变为 0 坐庄的概率

    但 0 存活到了最后,这是无法取的(事实上若 0 活到了最后,1 就不可能坐庄)

    那么 f[i][0] 其实是什么呢?

    f[i][i]!

    因为这是一个环,在剩余 i+1 个人时,删掉了第 i 个人,在坐庄时当然由第 0 人来,这时所有人都没有被重标号

     1 #include <cstdio>
     2 #include <cstring>
     3 const int sizeOfPlayer=55;
     4 const int sizeOfCard=55;
     5 
     6 inline int getint();
     7 
     8 int N, M;
     9 int a[sizeOfCard];
    10 double f[sizeOfPlayer][sizeOfCard];
    11 
    12 int main()
    13 {
    14     N=getint(), M=getint();
    15     for (int i=0;i<M;i++)
    16         a[i]=getint();
    17 
    18     for (int p=0;p<N;p++)
    19     {
    20         memset(f, 0, sizeof(f));
    21         f[N][(N-p)%N]=1.0;
    22         for (int i=N-1;i;i--)
    23         {
    24             for (int j=0;j<=i;j++)
    25                 for (int k=0;k<M;k++)
    26                     f[i][(j+a[k]-1)%(i+1)]+=f[i+1][j]/M;
    27             f[i][0]=f[i][i];
    28         }
    29 
    30         if (p) putchar(' ');
    31         printf("%.2lf%%", f[1][0]*100);
    32     }
    33 
    34     putchar('
    ');
    35 
    36     return 0;
    37 }
    38 
    39 inline int getint()
    40 {
    41     register int num=0;
    42     register char ch;
    43     do ch=getchar(); while (ch<'0' || ch>'9');
    44     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
    45     return num;
    46 }
    说的不清楚还请见谅
  • 相关阅读:
    uni-app中showModel会阻碍 uni.navigateBack跳转
    vue中使用Bus
    vue中class动态绑定值拼接字符串
    使用moment格式化
    sublimit中智能提示插件的安装
    element-table
    全球十大顶级俱乐部
    java的几种对象(PO,VO,DAO,BO,POJO)解释
    软件工程术语(上)
    职场秘笈:聪明人离职后必做的5件事
  • 原文地址:https://www.cnblogs.com/dyllalala/p/4176773.html
Copyright © 2011-2022 走看看