zoukankan      html  css  js  c++  java
  • 【BZOJ 3652】大新闻 数位dp+期望概率dp

    并不难,只是和期望概率dp结合了一下.
    稍作推断就可以发现加密与不加密是两个互相独立的问题,这个时候我们分开算就好了.
    对于加密,我们按位统计和就好了;对于不加密,我们先假设所有数都找到了他能找到的最好的匹配(就是异或后为二进制最高位与n-1相等的最大数)并且算出其异或后的总和,然后我们按位贪心,带着所有的数(一开始我们假设所有的数是小于等于二进制最高位与n-1相等的最大数的所有数)从高位走向低位,每走一步,如果这一位是0,就会导致一半的数在这一位不能是1,减去这一半的数在这一位上的贡献,如果这一位是1,就意味着一半的数往后一定会全部是1,我们把这一半数从我们带着的数中减去,另一半待定(留下).
    这样思路清晰,实现简易,只是一定注意贡献不要统计错.

    #include <cstdio>
    typedef double db;
    typedef long long LL;
    LL f,bin[61],n,temp;
    db ans1,ans2,p;
    int digit[61],bit,i,j;
    int main(){
      scanf("%lld%lf",&n,&p),bin[0]=1,temp=--n;//我的代码需要的是n-1
      while(temp)digit[++bit]=temp&1,temp>>=1,bin[bit]=bin[bit-1]<<1;
      for(i=bit;i>0;--i){
        f=temp;
        if(digit[i])f+=(n&(bin[i-1]-1))+1,temp+=bin[i-2];//这一位如果是1的话,对后面都有贡献,所以要累加temp
        ans1+=(db)f*(n-f+1)*2.*bin[i-1];
      }
      ans1=ans1/(n+1.)/(n+1.);
      ans2=(db)(n+1.)*(bin[bit]-1);
      temp=bin[bit]; 
      for(i=bit;i>0;--i)
        if(digit[i]&1)temp>>=1;
        else ans2-=(db)(temp>>1)*bin[i-1];
      ans2/=(n+1.);
      printf("%.6f
    ",ans1*(1.-p)+ans2*p);
      return 0;  
    }
  • 相关阅读:
    Hbase JavaApi
    面向对象特征之继承
    重写(Override)与重载(Overload)
    数组排序
    EL表达式
    java异常
    业务代码与非业务代码
    设计思想之高内聚低耦合
    JDBC实现动态查询
    枚举
  • 原文地址:https://www.cnblogs.com/TSHugh/p/8476934.html
Copyright © 2011-2022 走看看