【poj2096】Collecting Bugs
题目描述
有s个系统,n种bug,小明每天找出一个bug,可能是任意一个系统的,可能是任意一种bug,即是某一系统的bug概率是1/s,是某一种bug概率是1/n。
求他找到s个系统的bug,n种bug,需要的天数的期望。
输入
一行两个数分别表示n和s。
输出
一行一个数,表示天数的期望。
样例输入
1 2
样例输出
3.0000
题解
设 dp[ i ][ j ] 表示已经找到了 i 种bug,在 j 个系统里。考虑下一天,分为4种情况:
1.找到的bug不在前 i 种bug里,在 j 个系统里。此种情况概率 p1 = (n - i)*( j ) / ( n*s );
2.找到的bug在前 i 种bug里,不在 j 个系统里。这种情况概率p2 = i*(s-j) / ( n*s );
3.找到的bug不在前 i 种bug里,也不在 j 个系统里。这种情况概率p3 = (n-i) * (s-j) / ( n*s );
4.找到的bug在前 i 种bug里,也在 j 个系统里。这种情况概率p4 = (i*j) / ( n*s );
所以我们可以列出式子:dp[ i ][ j ] = dp[ i+1 ][ j ] * p1 + dp[ i ][ j+1 ] * p2 + dp[ i+1 ][ j+1 ] * p3+ dp[ i ][ j ] * p4 +1
移项: dp[ i ][ j ] = ( dp[ i+1 ][ j ] * p1 + dp[ i ][ j+1 ] * p2 + dp[ i+1 ][ j+1 ] * p3 + 1 ) / ( 1 - i * j / s * n )
化简得:dp[ i ][ j ] = ( dp[ i+1 ][ j ] * ( n - i ) * j + dp[ i ][ j + 1 ] * ( s - j ) * i + dp[ i + 1 ][j + 1 ] * ( s - j ) * ( n - i ) + n * s ) / ( n * s - i * j )
#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=1000+5; int n,s; double dp[maxn][maxn]; int main(){ cin>>n>>s; for(int i=n;i>=0;i--) for(int j=s;j>=0;j--){ if(i==n&&j==s) continue; dp[i][j]=(dp[i+1][j]*(n-i)*j+dp[i][j+1]*(s-j)*i+dp[i+1][j+1]*(s-j)*(n-i)+n*s)/(n*s-i*j); } printf("%.4lf\n",dp[0][0]); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步