zoukankan      html  css  js  c++  java
  • 简单的期望「状压dp」

    题意

    题解

    dp定义真的神,

    直接的想法是$f[x][maxn]$为第$x$个操作,状态$maxn$,$maxn$1<<200,好像没有暴力分高

    实际上我们可以这样定义$f[x][maxn][len][0/1]$表示后八位$maxn$,第九位01,第九位之后连续长度为$j$概率

    为什么这样定义

    实际上质因数分解后2的次数就是后面0的个数

    +1会破坏已有的0,操作数最多只有200个全部+1后八位已经足够

    最多只会影响到后九位一次

    考虑一种极限情况

    111111111111111

    现在在最后一位加一会进位

    1000000000000000,再怎么+1都不会再影响到九位之后了

    转移比较简单具体看代码

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 ll x,n,m,xx,opt,maxn,cnt;
     5 double p,ans=0;
     6 double f[210][288][310][2];
     7 ll cal(ll now){
     8     ll cnt=0;
     9     while(now%2==0) cnt++,now/=2;
    10     return cnt;
    11 }
    12 int main(){
    13 //    freopen("cnm.xlsx","w",stdout);
    14     scanf("%lld%lld%lf",&x,&n,&p);
    15     p/=100;
    16     xx=x;
    17     xx>>=8;
    18     opt=xx&1;
    19     maxn=(1<<8)-1;
    20     for(;xx&&((xx&1)==opt);xx>>=1)
    21         cnt++;
    22     if(cnt==0) cnt++;//
    23     m=cnt+n;
    24     f[0][x&maxn][cnt][opt]=1;
    25 //    printf("%lld
    ",m);
    26     for(ll i=1;i<=n;i++)
    27         for(ll pre=0;pre<=maxn;pre++)
    28             for(ll j=1;j<=m;j++)
    29                 for(ll t=0;t<=1;t++)
    30                 if(f[i-1][pre][j][t]){        
    31                     ll now,tt,jj;
    32                     now=pre+1;
    33                     if(now==(1<<8)){
    34                         now=0;tt=t^1;
    35                         if(t==1) jj=j;
    36                         else jj=1;
    37                     }
    38                     else jj=j,tt=t;
    39                     f[i][now][jj][tt]+=f[i-1][pre][j][t]*(1-p);
    40                     now=pre<<1;
    41                     if(((now>>8)&1)==t) tt=t,jj=j+1;    
    42                     else tt=t^1,jj=1;
    43                     now=now&maxn;
    44                     f[i][now][jj][tt]+=f[i-1][pre][j][t]*p;
    45                 }
    46     for(ll now=1;now<=maxn;now++)//
    47         for(ll j=1;j<=m;j++)
    48             for(ll t=0;t<=1;t++)
    49                 if(f[n][now][j][t])
    50                 ans+=f[n][now][j][t]*cal(now);
    51                 //,printf("f[%lld][%lld][%lld][%lld]=%lf
    ",n,now,j,t,f[n][now][j][t]);
    52 //    printf("%.13lf
    ",ans);
    53     for(ll j=1;j<=m;j++){
    54         ans+=f[n][0][j][0]*(j+8)+f[n][0][j][1]*8;
    55 //        printf("f[%lld][0][%lld][0]=%lf f[%lld][0][%lld][1]=%lf
    ",n,j,f[n][0][j][0],n,j,f[n][0][j][1]);
    56     }
    57     printf("%.13lf
    ",ans);
    58 }
    View Code
  • 相关阅读:
    JDBC操作MySQL
    MySQL-SQL语句
    MySQL-环境安装、配置、卸载、系统介绍
    JavaSE-单元测试、反射、注解
    JavaSE-Stream、方法引用
    JavaSE-函数式编程接口
    JavaSE-网络编程
    Document
    Document
    Document
  • 原文地址:https://www.cnblogs.com/znsbc-13/p/11719901.html
Copyright © 2011-2022 走看看