• [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 }
  • 相关阅读:
    CCF 认证
    ZOJ Light Bulb
    codeforce 605BE. Freelancer's Dreams
    HDU2546——背包DP——饭卡
    转载DD大神背包九讲
    背包九讲
    zstu4186——线段树——表白计划(未完成)
    zstu4189——后缀表达式——逻辑运算
    蛇形矩阵
    zs深入浅出学算法022——DFS———汉诺塔问题II
  • 原文地址:https://www.cnblogs.com/skylee03/p/7682246.html
Copyright © 2020-2023  润新知