博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2096 Collecting Bugs:期望dp
阅读量:5157 次
发布时间:2019-06-13

本文共 2488 字,大约阅读时间需要 8 分钟。

题目链接:

题意:

  有一个程序猿,他每天都会发现一个bug。

  bug共有n个种类。属于某一个种类的概率为1/n。

  有s个子系统,每个bug属于一个系统。属于某一个系统的概率为1/s。

  问你发现的bug能够覆盖到n个种类和s个系统的期望天数。

 

题解:

  期望dp转移的套路:

    倒着推。

    利用性质:期望 = ∑ (P(子期望)*φ(子期望))

 

  状态表示:

    dp[i][j] = expectation

    i:覆盖到i个种类

    j:覆盖到j个系统

    dp:从当前状态到达目标状态的期望天数(此状态的剩余天数)

 

  如何转移:

    套路。先考虑它能够转移到的子期望。

    now: dp[i][j]

    四种转移:

      (1)dp[i][j]:bug的没有覆盖新的区域。概率p0' = (i/n)*(j/s)

      (2)dp[i+1][j]:bug为新种类,不是新系统。概率p2 = (n-i)/n * j/s.

      (3)dp[i][j+1]:bug不是新种类,是新系统。概率p3 = i/n * (s-j)/s.

      (4)dp[i+1][j+1]:既是新种类,又是新系统。概率p4 = (n-i)/n*(s-j)/s

    利用期望性质:

      dp[i][j] = dp[i][j]*(i/n)*(j/s)

            + dp[i+1][j]*((n-i)/n)*(j/s)

            + dp[i][j+1]*(i/n)*((s-j)/s)

            + dp[i+1][j+1]*((n-i)/n)*((s-j)/s)

            + 1

    因为找到一个bug意味着过去了一天,所以dp[i][j]最后要+1。

    移项:

      dp[i][j] = (dp[i+1][j]*((n-i)/n)*(j/s)

            + dp[i][j+1]*(i/n)*((s-j)/s)

            + dp[i+1][j+1]*((n-i)/n)*((s-j)/s) + 1)

            / (1 - (i/n)*(j/s))

 

  边界条件:

    达到目标状态时,剩余天数为0。

    dp[n][s] = 0

 

AC Code:

1 // state expression: 2 // dp[i][j] = expectation 3 // i: found i kinds of bug 4 // j: in j different sys 5 // 6 // find the answer: 7 // ans = dp[n][s] 8 // 9 // transferring:10 // dp[i][j] = dp[i][j]*(i/n)*(j/s)11 //            + dp[i+1][j]*((n-i)/n)*(j/s)12 //            + dp[i][j+1]*(i/n)*((s-j)/s)13 //            + dp[i+1][j+1]*((n-i)/n)*((s-j)/s) + 114 //15 // dp[i][j] = (dp[i+1][j]*((n-i)/n)*(j/s)16 //            + dp[i][j+1]*(i/n)*((s-j)/s)17 //            + dp[i+1][j+1]*((n-i)/n)*((s-j)/s) + 1)18 //            / (1 - (i/n)*(j/s))19 //20 // boundary:21 // dp[n][s] = 022 #include 
23 #include
24 #include
25 #define MAX_N 100526 #define MAX_S 100527 28 using namespace std;29 30 int n,s;31 double dp[MAX_N][MAX_S];32 33 void read()34 {35 cin>>n>>s;36 }37 38 void solve()39 {40 memset(dp,0,sizeof(dp));41 for(int i=n;i>=0;i--)42 {43 for(int j=s;j>=0;j--)44 {45 if(i==n && j==s) continue;46 double p1=(double)(n-i)/n*j/s;47 double p2=(double)i/n*(s-j)/s;48 double p3=(double)(n-i)/n*(s-j)/s;49 double p0=1.0-(double)i/n*j/s;50 dp[i][j]=(dp[i+1][j]*p1+dp[i][j+1]*p2+dp[i+1][j+1]*p3+1)/p0;51 }52 }53 }54 55 void print()56 {57 printf("%.4f\n",dp[0][0]);58 }59 60 int main()61 {62 read();63 solve();64 print();65 }

 

转载于:https://www.cnblogs.com/Leohh/p/7533518.html

你可能感兴趣的文章
Esfog_UnityShader教程_遮挡描边(原理篇)
查看>>
26个高效工作的小技巧(转载)
查看>>
IP地址+时间戳对文件进行重命名
查看>>
格子地图生成导航网格
查看>>
缺省函数
查看>>
@Repository的作用
查看>>
spring基础
查看>>
2015年总结+2016年计划
查看>>
设计模式--------代理模式
查看>>
INSERT INTO table(xxx) VALUES (xxx)
查看>>
操作系统概论五
查看>>
ElasticSearch文档操作介绍三
查看>>
win10电脑配置
查看>>
python学习的第32天网络编程part2
查看>>
计算机可以这样玩—自我学习,自我思维,自我工作(编程)
查看>>
微星P55-主板是怎样造出来的
查看>>
CentOS 双网卡配置一个上外网一个接局域网
查看>>
java面向对象测试题(听说你学会了Java面向对象?!)
查看>>
使用pdfcrack破解PDF密码(Linux)
查看>>
(转)linux基本信息查看
查看>>