概率dp+例题

来源:互联网 发布:linux vi命令保存退出 编辑:程序博客网 时间:2024/05/19 23:59

http://kicd.blog.163.com/blog/static/126961911200910168335852/

讲解

例题

poj-2096

(代码转自http://blog.csdn.net/xingyeyongheng/article/details/25179481)

/*有S个系统,n中bug,程序员每天发现一个,现求发现n种bug存在s个系统中并且每个系统都要被发现bug的平均天数(期望)假设dp[i][j]表示已经发现i种bug存在j个系统中到目标状态所需的天数,显然dp[n][s]=0;从dp[i][j]经过一天后可能得到以下四种情况;dp[i][j]->dp[i+1][j+1];   在一个新的系统里面发现一个新的bugdp[i][j]->dp[i+1][j];    在原来已发现过bug的系统里发现一个新的bugdp[i][j]->dp[i][j+1];   在一个新的系统里面发现一个已被发现过的bugdp[i][j]->dp[i][j];   在已发现过bug的系统发现已发现过的bug 四种达到的概率分别是p1=(n-i)*(s-j)/(n*s);p2=(n-i)*j/(n*s);p3=i*(s-j)/(n*s);p4=i*j/(n*s);然后根据E(aA+bB+cC+dD+...)=aEA+bEB+....;      a,b,c,d...表示概率,A,B,C...表示状态dp[i][j]=p1*dp[i+1][j+1]+p2*dp[i+1][j]+p3*dp[i][j+1]+p4*dp[i][j]+1;=>dp[i][j]=(p1*dp[i+1][j+1]+p2*dp[i+1][j]+p3*dp[i][j+1]+1)/(1-p4);*/#include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int MAX=1000+10;int n,s;double dp[MAX][MAX],p1,p2,p3,p4;int main(){    while(cin>>n>>s)    {        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;                p1=(n-i)*(s-j)*1.0;                p2=(n-i)*j*1.0;                p3=i*(s-j)*1.0;                p4=n*s-i*j*1.0;                dp[i][j]=(p1*dp[i+1][j+1]+p2*dp[i+1][j]+p3*dp[i][j+1]+n*s)/p4;            }        }        printf("%.4lf\n",dp[0][0]);    }    return 0;}

然后是今天在codeforces上面看到的一道题

398B - Painting The Wall

#include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int MAX=2000+10;int n,m;int vis[2][MAX];double dp[MAX][MAX],p1,p2,p3,p4;int main(){    int n,m;    scanf("%d %d",&n,&m);    memset(vis,0,sizeof vis);    int cntx=0;    int cnty=0;    while(m--)    {        int x,y;        scanf("%d %d",&x,&y);        if(!vis[0][x])            cntx++;        if(!vis[1][y])            cnty++;        vis[0][x]=vis[1][y]=1;    }    memset(dp,0,sizeof dp);    for(int i=n;i>=cntx;i--)    {        for(int j=n;j>=cnty;j--)        {            if(i==n&&j==n)                continue;            p1=(n-i)*(n-j)*1.0;            p2=(n-i)*j*1.0;            p3=i*(n-j)*1.0;            p4=n*n-i*j*1.0;            dp[i][j]=(p1*dp[i+1][j+1]+p2*dp[i+1][j]+p3*dp[i][j+1]+n*n)/p4;        }    }    printf("%.4f\n",dp[cntx][cnty]);}


0 0
原创粉丝点击