Descriptionios
Inputgit
Outputapp
Sample Inputpost
1 2
Sample Outputui
3.0000
一個軟件有 s 個子系統,存在 n 種 bug。某人一天能找到一個 bug。問,在這個軟件中找齊 n 種 bug,this
而且每一個子系統中至少包含一個 bug 的時間的指望值(單位:天)。注意:bug 是無限多的,每一個 bugspa
屬於任何一種 bug 的機率都是 1/n;出如今每一個系統是等可能的,爲 1/s。rest
令 f[i][j] 表示已經找到了 i 種 bug,且 j 個子系統至少包含一個 bug,距離完成目標須要的時間的指望。code
目標狀態是 f[0][0]component
再過一天找到一個 bug 多是以下的狀況:
1. 這個 bug 的種類是 已經找到的 而且 出如今 已經找到 bug 的子系統中
2. 這個 bug 的種類是 已經找到的 而且 出如今 沒有找到 bug 的子系統中
3. 這個 bug 的種類是 沒有找到的 而且 出如今 已經找到 bug 的子系統中
4. 這個 bug 的種類是 沒有找到的 而且 出如今 沒有找到 bug 的子系統中
通過簡單的分析,不可貴出以下遞推過程:
f[i][j] = i/n*j/s*f[i][j]
+ i/n*(s-j)/s*f[i][j+1]
+ (n-i)/n*j/s*f[i+1][j]
+ (n-i)/n*(s-j)/s*f[i+1][j+1]
移項可得
(1-(i*j)/(n*s))f[i][j] = i/n*(s-j)/s*f[i][j+1]
+ (n-i)/n*j/s*f[i+1][j]
+ (n-i)/n*(s-j)/s*f[i+1][j+1]
逆向遞推便可
注意這道題輸出的是f[0][0],而不是f[1][1]。
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; double f[1005][1005]; int main() { int n,s; while(scanf("%d%d",&n,&s)!=EOF) { memset(f,0,sizeof(f)); for(int i=n;i>=0;i--) { for(int j=s;j>=0;j--) { if(i==n&&j==s) continue; double p1=double(s-j)*i/n/s; double p2=double(n-i)*j/n/s; double p3=double(n-i)*(s-j)/n/s; double p0=1.0-double(i*j)/n/s; f[i][j]=p1*f[i][j+1]+p2*f[i+1][j]+p3*f[i+1][j+1]+1; //+1應該是由於要多進行一次因此+1 f[i][j]/=p0; } } printf("%.4f\n",f[0][0]); } return 0; }