E40 概率DP 求期望
视频链接:https://www.bilibili.com/video/BV1Wh4y1p7Zg/
题意:
一个软件有s个子系统,会产生n种bug
某人一天发现一个bug,这个bug属于一个子系统,属于一个分类
每个bug属于某个子系统的概率是1/s,属于某种分类的概率是1/n
问:发现n种bug,s个子系统都发现bug的期望天数
#include <cstdio> using namespace std; int n,s; double f[1010][1010]; int main(){ scanf("%d %d", &n, &s); f[n][s]=0; for(int i=n; i>=0; i--){ for(int j=s; j>=0; j--){ if(i==n && s==j) continue; f[i][j]=(f[i][j+1]*i*(s-j)+f[i+1][j]*(n-i)*j+f[i+1][j+1]*(n-i)*(s-j)+n*s)/(n*s-i*j); } } printf("%.4lf\n", f[0][0]); }
Luogu P1850 [NOIP2016 提高组] 换教室
题意:同课申请换教室,概率通过,求路程和的最小期望
时间:300^3+2000^2
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=2005; int n,m,v,e,c[N],d[N]; double p[N],dis[N][N],f[N][N][2]; int main(){ cin>>n>>m>>v>>e;//时段数n,可换m节,教室数量v,道路数量e for(int i=1;i<=n;i++) scanf("%d",&c[i]); //上课教室 for(int i=1;i<=n;i++) scanf("%d",&d[i]); //同课教室 for(int i=1;i<=n;i++) scanf("%lf",&p[i]);//通过概率 for(int i=1;i<=v;i++) for(int j=1;j<i;j++) dis[i][j]=dis[j][i]=2e9; for(int i=1;i<=e;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); dis[a][b]=dis[b][a]=min(dis[a][b],1.0*c); //连边 } for(int k=1;k<=v;k++) //Floyd求最短路 for(int i=1;i<=v;i++) for(int j=1;j<i;j++) if(dis[i][k]+dis[k][j]<dis[i][j]) dis[i][j]=dis[j][i]=dis[i][k]+dis[k][j]; for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) f[i][j][0]=f[i][j][1]=2e9; f[1][0][0]=f[1][1][1]=0; for(int i=2;i<=n;i++){ //第i时段 for(int j=0;j<=min(m,i);j++){ //已用了j次机会 f[i][j][0]=min(f[i-1][j][0] //上次不换 +dis[c[i-1]][c[i]], f[i-1][j][1] //上次申请换 +dis[c[i-1]][c[i]]*(1-p[i-1]) +dis[d[i-1]][c[i]]*p[i-1]); if(j>0) f[i][j][1]=min(f[i-1][j-1][0] //上次不换 +dis[c[i-1]][c[i]]*(1-p[i]) +dis[c[i-1]][d[i]]*p[i], f[i-1][j-1][1] //上次申请换 +dis[c[i-1]][c[i]]*(1-p[i-1])*(1-p[i]) +dis[c[i-1]][d[i]]*(1-p[i-1])*p[i] +dis[d[i-1]][c[i]]*p[i-1]*(1-p[i]) +dis[d[i-1]][d[i]]*p[i-1]*p[i]); } } double ans=2e9; for(int i=0;i<=m;i++) ans=min(ans,min(f[n][i][0],f[n][i][1])); printf("%.2lf",ans); }
练习: