Title Link: http://poj.org/problem?id=2096
Test instructions
A software has s subsystem, will produce n kinds of bugs.
Someone finds a bug in a day that is part of a bug that happens in a subsystem.
Find all n bugs, and each subsystem finds a bug so that the desired number of days is expected.
Note that: The number of bugs is infinite, so found a bug, the probability of appearing in a subsystem is 1/S,
The probability of belonging to a certain type is 1/n.
Solution:
DP[I][J] Indicates that I have found the bug, and exists in the J subsystem, the desired number of days to reach the target state.
Obviously, dp[n][s]=0, because the goal has been achieved. and Dp[0][0] is the answer we ask for.
DP[I][J] state can be converted into the following four kinds:
DP[I][J] found a bug that was found in I Bug and J subsystem
DP[I+1][J] found a bug that belongs to a new bug, but belongs to the J subsystem that has been found
Dp[i][j+1] found a bug belonging to the I bug found, but belongs to the new subsystem
Dp[i+1][j+1] found a bug that belongs to a new bug and a new subsystem
So:
DP[I][J] = I/n*j/s*dp[i][j] + (n-i)/n*j/s*dp[i+1][j] + i/n* (s-j)/s*dp[i][j+1] + (n-i)/n* (s-j)/s*dp[i+1][j+1] +1
To move an item:
(1-I*J/N/S) Dp[i][j] = (n-i)/n*j/s*dp[i+1][j] + i/n (S-J)/s*dp[i][j+1] + (n-i)/n* (s-j)/s*dp[i+1][j+1] +1
Code:
#include <stdio.h>#include <string.h>#include <vector>#include <string>#include <algorithm>#include <iostream>#include <iterator>#include <fstream>#include <set>#include <map>#include <math.h>using namespace STD;Doubledp[1010][1010];intn, S;intMain () { while(Cin>> N >> s) {memset(DP,0,sizeof(DP)); for(inti = n; I >=0; i--) for(intj = S; J >=0; j--) {if(i = = N && j = = s)Continue;DoubleANS1 = (Double(n-i) *j)/n/s* Dp[i +1][J];DoubleAns2 = (Double(s-j) *i)/n/s* Dp[i][j +1];DoubleANS3 = (Double(n-i) * (s-j))/n/s* Dp[i +1][j +1]; DP[I][J] = (ans1 + ans2 + ans3 +1) / (1.0- (Double(i) *j/n/s)); }printf("%.4LF", dp[0][0]); }return 0;}
POJ 2096 Collecting Bugs "Probability DP"