• 【xsy1596】旅行 期望+状压DP


    题目大意:有$m$个人要从城市$1$开始,依次游览城市$1$到$n$。

    每一天,每一个游客有$p_i$的概率去下一个城市,和$1-p_i$的概率结束游览。

    当游客到达城市$j$,他会得到$(1+frac{C_j}{C_{j-1}})H_{i,j}$的收益,其中$C_i$表示到访第$i$个城市的人数。

    问所有人的期望收益。

    数据范围:$n,m≤16$

    我们考虑状压$DP$

    设$f[i][S]$表示到达城市i的人群为$S$的概率。

    设$ans[i][S]$表示到达城市i的人群为$S$时,所有人在前$i$座城市的收益和。

    不难推出:

    $f[i][S]=sumlimits_{S∈P} f[i-1][P] imes chg(P,S)$

    $ans[i][S]=sumlimits_{S∈P} ig(ans[i-1][P]+f[i-1][P] imes sum[i][S] imes (1+frac{|S|}{|P|})ig) imes chg(P,S)$

    其中,$chg(P,S)$表示前一次游览的人群为$P$,下一次剩下$S$的概率。简单乘一下就行了。

    这么转移的复杂度是$O(n imes 3^m)$的,然而他T了。。。。

     1 #include<bits/stdc++.h>
     2 #define M 16
     3 #define get orzmyh
     4 using namespace std;
     5 
     6 int m,n,all=0;
     7 
     8 double p[M+1]={0},h[M+1][M+1]={0},mulp[1<<M]={0},fmulp[1<<M]={0};
     9 double f[M+1][1<<M]={0},ans[M+1][1<<M]={0},mo[1<<M]={0},sum[M+1][1<<M]={0};
    10 
    11 double Get(int P,int S){
    12     return mulp[P&S]*fmulp[P^S];
    13 }
    14 double Sum(int day,int S){
    15     double res=0;
    16     for(int i=0;i<m;i++) if((1<<i)&S){
    17         res+=h[i][day];
    18     }
    19     return res;
    20 }
    21 
    22 int main(){
    23     scanf("%d%d",&m,&n); all=(1<<m); 
    24     for(int i=1;i<all;i++) mo[i]=mo[i>>1]+(i&1);
    25     for(int i=0;i<m;i++) scanf("%lf",p+i);
    26     
    27     for(int i=0;i<all;i++){
    28         double mul1=1,mul2=1;
    29         for(int j=0;j<m;j++)
    30         if(i&(1<<j)){
    31             mul1=mul1*p[j];
    32             mul2=mul2*(1-p[j]);
    33         }
    34         mulp[i]=mul1;
    35         fmulp[i]=mul2;
    36     }
    37     
    38     for(int i=0;i<m;i++)
    39     for(int j=1;j<=n;j++)
    40     scanf("%lf",&h[i][j]);
    41     
    42     for(int i=1;i<=n;i++){
    43         for(int S=1;S<all;S++)
    44         sum[i][S]=Sum(i,S);
    45     }
    46     f[1][all-1]=1; ans[1][all-1]=sum[1][all-1];
    47     for(int i=2;i<=n;i++){    
    48         for(int P=0;P<all;P++)
    49         for(int S=P;~S;S=P&(S-1)){
    50             double val=Get(S,P);
    51             f[i][S]+=f[i-1][P]*val;
    52             ans[i][S]+=(ans[i-1][P]+(mo[P]?sum[i][S]*(1+mo[S]/mo[P])*f[i-1][P]:0))*val;
    53             if(S==0) break;
    54         }
    55     }
    56     double Ans=0;
    57     for(int S=0;S<all;S++)
    58     Ans+=ans[n][S];
    59     printf("%.10lf
    ",Ans);
    60 }

    于是我后来写了一个$O(nm imes 2^m)$的,代码如下:

     1 #include<bits/stdc++.h>
     2 #define M 17
     3 using namespace std;
     4 
     5 double f[M][M]={0},h[M][M]={0},p[M]={0};
     6 int n,m;
     7 
     8 int main(){
     9     scanf("%d%d",&m,&n);
    10     for(int i=1;i<=m;i++) scanf("%lf",p+i);
    11     for(int i=1;i<=m;i++){
    12         f[i][1]=1;
    13         for(int j=2;j<=n;j++)
    14         f[i][j]=f[i][j-1]*p[i];
    15     }
    16     double ans=0;
    17     for(int i=1;i<=m;i++){
    18         for(int j=1;j<=n;j++){
    19             scanf("%lf",&h[i][j]);
    20             ans+=f[i][j]*h[i][j];
    21         }
    22     }
    23     for(int i=1;i<n;i++){
    24         for(int s=1;s<(1<<m);s++){
    25             double ps=1,sum=0,pn=0; int cnt=0;
    26             for(int j=1;j<=m;j++) if(s&(1<<(j-1))){
    27                 ps*=f[j][i];
    28                 cnt++;
    29                 pn+=p[j];
    30             }else ps*=1-f[j][i];
    31             
    32             for(int j=1;j<=m;j++) if(s&(1<<(j-1)))
    33             sum+=p[j]*h[j][i+1]*(pn-p[j]+1);
    34             ans+=ps*sum/cnt;
    35         }
    36     }
    37     printf("%.10lf
    ",ans);
    38 }
  • 相关阅读:
    制品库 Jfrog Artifactory 搭建私服
    发布制品到私服 Nexus
    项目中如何使用私服 Nexus
    Centos7 上手 Docker 容器及 dockercompose
    项目使用 Jfrog Artifactory 制品库
    企业DevOps之路:Jenkins 整合 SonarQube代码质量自动扫描
    发布制品到 Jfrog Artifactory
    企业DevOps之路:私有镜像仓库 Harbor 搭建
    项目管理和缺陷跟踪系统 Redmine
    Nexus 私有制品库搭建
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10694131.html
Copyright © 2020-2023  润新知