ZOJ 3605 Find the Marble

来源:互联网 发布:流体 热能 仿真软件 编辑:程序博客网 时间:2024/06/05 07:07

转载自 http://blog.sina.com.cn/s/blog_5123df350100zp0s.html
照着题解写一次,就当自己懂了。
zoj 和virtual oj 都挂了。好像。。

n个罐子,有一个石头放在第s号罐子里,然后交换这些罐子m次,只能记住k次,每次交换被忘掉的概率相同,那个猜的人(按概率最大的猜)最可能猜哪号罐子里有石头。用dp[i][j][k]表示交换了i次,忘掉了j次,石头在k号罐子里的概率。知道dp[i-1][j][t]开始推,如果它忘掉了这次dp[i][j+1][t]+=dp[i-1][j][t]*p2。如果没忘掉这次,如果这次交换(x,y)有x==t,则dp[i][j][y]+=dp[i-1][j][t]*p1,同理如果y==t则dp[i][j][y]+=dp[i-1][j][t]*p1;否则的话dp[i][j][t]=dp[i-1][j][t]*p1。其中p1是没忘记的概率,p2是忘记的概率p1=k/m , p2=1-p1。 初始dp[0][0][s]=1。最终求argmax{dp[m][m-k][x]}。

#include<stdio.h>#include<algorithm>#include<string.h>struct  sp{    int x,y;}p[100];double  dp[100][100][100];int main(){//  freopen("F:\\123.txt","r",stdin);        int t,m,n,k,s;    scanf("%d",&t);    for(int ik=1;ik<=t;ik++)    {       scanf("%d%d%d%d",&n,&m,&k,&s);       for(int i=1;i<=m;i++)        {            scanf("%d%d",&p[i].x ,&p[i].y );        }     memset(dp,0,sizeof(dp));     double p1=(double)k/m,p2=(double)1-p1;      // printf("%f %f\n",p1,p2);       dp[0][0][s]=1;       for(int i=1;i<=m;i++)      {         for(int j=0;j<=m-k &&j<=i;j++)         {            for(int u=1;u<=n;u++)            {               dp[i][j+1][u]+=dp[i-1][j][u] *p2;         // printf("see %d %d\n",p[i].x ,u);                if(p[i].x ==u )                {                   dp[i][j][p[i].y ]+=dp[i-1][j][u]*p1;        //    printf("look %d %f\n",p[i].y ,dp[i][j][p[i].y ]);                }else if(p[i].y ==u)                 {                    dp[i][j][p[i].x ]+=dp[i-1][j][u]*p1;                 }                 else                 {                     dp[i][j][u]+=dp[i-1][j][u];        /* 题解一开始漏了说这种转移情况,然后我用codeblock演算过程,发现当    p[i].x ==u 和    p[i].y ==u 都不成立的时候,应该        有       dp[i][j][u]+=dp[i-1][j][u]; 情况,即是看到了,但是交换的两个罐子都不含有硬币。。。即当前状态,需要继承i-1时的状态*/                 }            }         }      }        int maxi=1;        for(int i=1;i<=n;i++)        {        //  printf("%d %f\n",i,dp[m][m-k][i]);            if(dp[m][m-k][i]>dp[m][m-k][maxi])            {                maxi=i;            }          }          printf("%d\n",maxi);    }    return 0;}
0 0
原创粉丝点击