POJ2096
题目链接:http://poj.org/problem?id=2096
题目大意:一个人很爱收集程序中的bug(这收藏爱好……),一天能找一个,他还把程序中的bug分成了n个类别。现在有一个含有s个子系统的程序,问找齐n种bug,并且每个子系统中都找到一个bug的期望时间(单位:天)。注意:bug无限多(这种程序还敢出版……)
关键点:分类讨论
首先,由于bug无限多,因此我们可以推断,每找到一个bug,它属于任何一个类别的概率都是1/n,属于任何一个子系统的概率都是1/s。
因此,令f[i,j]表示找到了i种bug,且有j个子系统找到至少一个bug后完成任务的期望时间。
不难推断有以下四种情况:
1. 找到的bug来自于已找到的i种bug中,属于已出现bug的j个子系统当中
2. 找到的bug来自于未找到的(n-i)种bug中,属于已出现bug的j个子系统当中
3. 找到的bug来自于已找到的i种bug中,属于未出现bug的(s-j)个子系统当中
4. 找到的bug来自于未找到的(n-i)种bug中,属于未出现bug的(s-j)个子系统当中
然后我们就得到了:
f[i,j]=(i/n)*(j/s)*f[i,j]
+(i/n)*(1-j/s)*f[i,j+1]
+(1-i/n)*(j/s)*f[i+1,j]
+(1-i/n)*(1-j/s)*f[i+1,j+1]+1//找一个bug要一天
然后移项:
[1-(i/n)*(j/s)]f[i,j]=(i/n)*(1-j/s)*f[i,j+1]
+(1-i/n)*(j/s)*f[i+1,j]
+(1-i/n)*(1-j/s)*f[i+1,j+1]+1
于是我们要的转移方程就有了。最后放代码:
var n,s,i,j:longint;
f:array[0..1001,0..1001]of extended;
procedure main;
var sol:array[1..4]of extended;
begin
fillchar(f,sizeof(f),0);
for i:=n downto 0 do
for j:=s downto 0 do
begin
if(i=n)and(j=s) then continue;
sol[1]:=1-(i*j)/(n*s);
sol[2]:=i*(s-j)/(n*s)*f[i,j+1];
sol[3]:=(n-i)*j/(n*s)*f[i+1,j];
sol[4]:=(n-i)*(s-j)/(n*s)*f[i+1,j+1];
f[i,j]:=(sol[2]+sol[3]+sol[4]+1)/sol[1];
end;
writeln(f[i,j]:0:4);
end;
begin
while not eof do
begin
readln(n,s);
main;
end;
end.