LightOJ-1265-Island of Survival (概率dp)

来源:互联网 发布:淘宝装修市场 编辑:程序博客网 时间:2024/05/21 10:51

题目链接:LightOJ-1265-Island of Survival

dp[i][j] 表示 i个狼,j个鹿时人存活的概率。
考虑到五种情况,得出状态转移方程:

dp[i][j]=2ij(i+j+1)(i+j)dp[i][j1]+i(i1)(i+j+1)(i+j)dp[i2][j]+j(j1)(i+j+1)(i+j)dp[i][j]

+max(2j(i+j+1)(i+j)dp[i][j],2j(i+j+1)(i+j)dp[i][j1])

不过代码T了。。

#include<bits/stdc++.h>using namespace std;double dp[1007][1007];const double eps=1e-12;int main(){    int T;    scanf("%d",&T);    for(int kase=1;kase<=T;kase++)    {        int n,m;        scanf("%d%d",&n,&m);        for(int i=0;i<=m;i++) dp[0][i]=1;        for(int i=1;i<=n;i++)        {            for(int j=0;j<=m;j++)            {                double fm=1;                fm-=j*(j-1)*1.0/(i+j+1)/(i+j);                double ans=0;                if(j>=1) ans+=2*j*i*dp[i][j-1]/(i+j+1)/(i+j);                if(i>=2) ans+=i*(i-1)*dp[i-2][j]/(i+j+1)/(i+j);                if(j>=1)                {                    double t=ans+2*j*dp[i][j-1]/(i+j+1)/(i+j);                    ans=max(t/fm,ans/(fm-2.0*j/(i+j+1)/(i+j)));                }                dp[i][j]=ans;            }        }        printf("Case %d: %.15f\n",kase,dp[n][m]);    }    return 0;}

还有一种方法就是观察题目可以发现若没有虎,则必存活,若虎的数量为奇数,必死亡,若虎的数量是偶数。则忽略鹿的数量(鹿对游戏不产生影响),每次选取两只虎的概率是 n1n+1 ,连乘即可。

#include<bits/stdc++.h>using namespace std;int main(){    int T;    scanf("%d",&T);    for(int kase=1;kase<=T;kase++)    {        int n,m;        scanf("%d%d",&n,&m);        if(n==0) printf("1.0000000000000\n");        else if(n%2==1) puts("0.00000000000000");        else        {            double ans=1;            while(n)            {                ans*=(n-1.0)/(n+1.0);                n-=2;            }            printf("%.15f\n",ans);        }    }}
0 0