题意:Ivan每天能找到一个bug,现在有一个工程,有n种bug,s个子系统。问在这个工程中找出n种bug并且每个子系统至少有1个bug的天数的期望是多少。
思路:用dp[i][j]表示当前找出了i种bug,这些bug在j个子系统中,那么再找一个bug可能的情况有下面几种。
①找到的这个bug不在找到的i种bug中,但是在已经出现bug的j个子系统中。
②找到的这个bug在找到的i种bug中,但是不在已经出现bug的j个子系统中。
③找到的这个bug不在找到的i种bug中,并且不在已经出现bug的j个子系统中。
④找到的这个bug在找到的i种bug中,并且在已经出现bug的j个子系统中。
根据上面四种情况进行转移。详细看代码~
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=1000+10;
double dp[maxn][maxn];
bool flag[maxn][maxn];
int n,s;
double f(int x,int y)
{
if(x==n&&y==s) return 0;
if(x>n||y>s) return 0;
if(flag[x][y]) return dp[x][y];
flag[x][y]=true;
dp[x][y]=f(x+1,y)*(n-x)/n*y/s+f(x,y+1)*x/n*(s-y)/s+1;
dp[x][y]+=f(x+1,y+1)*(n-x)/n*(s-y)/s;
dp[x][y]/=(1-(double)x*y/n/s);
return dp[x][y];
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scanf("%d%d",&n,&s))
{
memset(flag,0,sizeof(flag));
double ans=f(0,0);
printf("%.4lf\n",ans);
}
return 0;
}