Find the Marble ZOJ - 3605 概率dp

96 篇文章 0 订阅
64 篇文章 0 订阅

题意:

有n个pots,其中只有第s个pots中有marble,进行m次交换,小明只看到k次交换,问他最有可能猜marble在哪个位置的pots上?


代码:

推发生概率,可以转换成对情况数的统计,哪种情况多说明哪种概率大。

用动态规划可以统计出来。

dp[i][j][k]分别表示前i次交换看到j次marble在第k个pots的情况数量。

转移方程大概不难想,但是细节要注意下。

假设当前交换了x和y,对于x、y来说转移方程为

dp[i][j][x]=dp[i-1][j][x]+dp[i-1][j-1][y],dp[i][j][y]=dp[i-1][j][y]+dp[i-1][j-1][x].

对于x和y之外的其它位置,转移方程为

dp[i][j][k]=dp[i-1][j][k]+dp[i-1][j-1][k];

dp[i-1][j][k]好理解,继承上一次交换是就看到了j次落在k位置的情况,对于每个位置来说都是一样的,然后对于x和y来说,从dp[i-1][j-1]的情况转移到dp[i][j]的话说明看到了当前这次交换,那么应该继承要交换位置的情况,而对于其他位置来说,虽然看到了交换,但是与自己无关,所以仍然继承自己位置的情况。


要注意的细节问题是,dp[i][0][s]=1对于0<=i<=m都要初始化为1,含义容易想。


代码:

#include <bits/stdc++.h>
using namespace std;
long long dp[55][55][55];
int x, y;
int use(int u)
{
    if(u==x)return y;
    if(u==y)return x;
    return u;
}
int main()
{
    int  i, j, t, n, m, k, s;
    cin>>t;
    while(t--)
    {
        memset(dp, 0, sizeof(dp));
        scanf("%d%d%d%d", &n, &m, &k, &s);
        for(i=0; i<=m; i++)dp[i][0][s]=1;
        for(i=1; i<=m; i++)
        {
            scanf("%d%d", &x, &y);
            for(j=1; j<=min(k, i); j++)
            {
               for(int e=1; e<=n; e++)
               {
           //      if(e==x || e==y)continue;
                 dp[i][j][e]=dp[i-1][j][e]+dp[i-1][j-1][e];
               }
                dp[i][j][x]=dp[i-1][j][x]+dp[i-1][j-1][y];
                dp[i][j][y]=dp[i-1][j][y]+dp[i-1][j-1][x];
                //dp[i][j][y]+=dp[i-1][j-1][y];
                //printf("i%d j%d %lld %lld\n", i, j,  dp[i][j][x], dp[i][j][y]);
                //dp[i][j][x]+=dp[i-1][j-1][x];
               // printf("i%d j%d %lld %lld\n", i, j,  dp[i][j][x], dp[i][j][y]);
            }          
        }
        j=1;
        for(i=1; i<=n; i++)
        {
            if(dp[m][k][i]>dp[m][k][j])j=i;
        }
        printf("%d\n", j);
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值