poj2096 Collecting Bugs(概率dp)

关键词:期望dp——剩余状态
题意:每次在n个程序中的某一个中找出s种bug中的一种。程序和bug种类的选择都是随机的。求至少每个程序中都找到一个bug且s种bug都找到的期望步数。
状态设计:状态维是当前状态,状态含义是到达末尾状态还需要的期望步数
dp[i][j]:已在i个程序中找到共j种bug,此时到达结尾还需要的期望步数
dp[i][j]可以转移到dp[i][j],dp[i+1][j],dp[i][j+1],dp[i+1][j+1]。而求期望步数则反过来由后者的期望步数可得到前者的期望步数。
dp[i][j]=(i/n)(j/s)*dp[i][j]+(1-i/n)(j/s)dp[i+1][j]+(i/n)(1-j/s)dp[i][j+1]+(1-i/n)*(1-j/s)*dp[i+1][j+1]+1
整理后可以得到dp[i][j]的递推公式
初始条件:dp[n][s]=0

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<set>
#include<vector>
#include<map>
#define ll long long
using namespace std;

const int maxn = 1000+10;

int n,s;
double dp[maxn][maxn];

int main(){
    while(scanf("%d%d",&n,&s)!=EOF){
        memset(dp,0,sizeof(dp));
        for(int i=n;i>=0;i--){
            for(int j=s;j>=0;j--){
                if(i==n&&j==s) continue;
                dp[i][j]=(double)((n-i)*j*dp[i+1][j]+(n-i)*(s-j)*dp[i+1][j+1]+i*(s-j)*dp[i][j+1]+n*s)/(double)(n*s-i*j);
            }
        }
        printf("%.4lf\n",dp[0][0]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值