zoukankan      html  css  js  c++  java
  • [CodeForces-441E]Valera and Number

    题目大意:
      给你一个数x,进行k次操作:
      1.有p%的概率将x翻倍;
      2.有1-p%的概率将x加1。
      问最后二进制下x末尾0个数的期望。

    思路:
      动态规划。
      由于k只到200,所以每次修改只与最后8位有关。
      f[i][x][y][z]表示操作次数为i时,末尾8为表示的数字为x,第9位为y,第9位及以上和第9位数字连续相同的长度。
      对于两种情况分别转移,注意特判超过8位的进位。
      最后计算期望的时候,可以枚举第一维为k的所有状态,然后通过状态可以直接计算出末尾0的数量,乘上概率即可。

     1 #include<cstdio>
     2 #include<cctype>
     3 inline int getint() {
     4     register char ch;
     5     while(!isdigit(ch=getchar()));
     6     register int x=ch^'0';
     7     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     8     return x;
     9 }
    10 const int K=201;
    11 double f[K][256][2][230];//[処理回数][末尾8bit][9bit目の値][9bit目の値が上にいくつ連続するか]
    12 int main() {
    13     int x=getint(),k=getint();
    14     double p=getint()/100.0;
    15     //初始状态
    16     int cnt=0,tmp=x>>8;
    17     while(tmp&&((tmp&1)==((x>>8)&1))) {
    18         tmp>>=1;
    19         cnt++;
    20     }
    21     f[0][x&255][(x>>8)&1][cnt]=1;
    22     for(register int i=0;i<k;i++) {
    23         for(register int x=0;x<=255;x++) {
    24             for(register int y=0;y<2;y++) {
    25                 for(register int z=0;z<230;z++) {
    26                     /*times 2*/
    27                     f[i+1][(x<<1)&255][(x>>7)&1][(((x>>7)&1)^y)?1:(z+1)]+=f[i][x][y][z]*p;
    28                     /*plus 1*/
    29                     if(x==255) {//特殊情况:考虑最后八位存不下而进位的情况 
    30                         if(y) {//如果第九位是1,则相当于前面那么多1都变成0 
    31                             f[i+1][0][0][z]+=f[i][x][y][z]*(1-p);
    32                         } else {//如果第九位是0,则相当于把这个0变成1 
    33                             f[i+1][0][1][1]+=f[i][x][y][z]*(1-p);//这里把9位以后的1算作多少都没关系,因为反正最后统计的是0 
    34                         }
    35                     } else {
    36                         f[i+1][x+1][y][z]+=f[i][x][y][z]*(1-p);
    37                     }
    38                 }
    39             }
    40         }
    41     }
    42     //计算期望
    43     double ans=0;
    44     for(register int x=0;x<=255;x++) {
    45         for(register int y=0;y<2;y++) {
    46             for(register int z=0;z<230;z++) {
    47                 int cnt=0,tmp=x;
    48                 while(cnt<8&&!(tmp&1)) {
    49                     cnt++;
    50                     tmp>>=1;
    51                 }
    52                 if(!y&&cnt==8) cnt+=z;
    53                 ans+=f[k][x][y][z]*cnt;
    54             }
    55         }
    56     }
    57     printf("%.13f
    ",ans);
    58     return 0;
    59 }
  • 相关阅读:
    POJ 1703 Find them, Catch them
    POJ 2236 Wireless Network
    POJ 2010 Moo University
    POJ 2184 Cow Exhibition
    POJ 3280 Cheapest Palindrome
    POJ 3009 Curling 2.0
    POJ 3669 Meteor Shower
    POJ 2718 Smallest Difference
    POJ 3187 Backward Digit Sums
    POJ 3050 Hopscotch
  • 原文地址:https://www.cnblogs.com/skylee03/p/7682246.html
Copyright © 2011-2022 走看看