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 }
    说的不清楚还请见谅
  • 相关阅读:
    Android Media Playback 中的MediaPlayer的用法及注意事项(二)
    Android Media Playback 中的MediaPlayer的用法及注意事项(一)
    34. Search for a Range
    33. Search in Rotated Sorted Array
    32. Longest Valid Parentheses
    31. Next Permutation下一个排列
    30. Substring with Concatenation of All Words找出串联所有词的子串
    29. Divide Two Integers
    28. Implement strStr()子串匹配
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/dyllalala/p/4176773.html
Copyright © 2011-2022 走看看