bzoj3191: [JLOI2013]卡牌游戏

本文介绍了一种使用概率动态规划解决特定杀人游戏问题的方法。通过定义状态f[i][j][k]来表示主角存活的概率,并给出了详细的转移方程。文章还提供了一段完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接

https://www.lydsy.com/JudgeOnline/problem.php?id=3191

题解

f[i][j][k] f [ i ] [ j ] [ k ] 表示我现在算第 i i 个人(主角)活到最后的概率,已经死了j个人,庄主是从 i i 开始数的第k个人(还没抽卡)的概率。
枚举卡,然后算出将要被杀的那个人是 kill=(k+a[card]1)mod(nj) k i l l = ( k + a [ c a r d ] − 1 ) mod ( n − j ) ,下一轮的庄主是 next=(kill+1)mod(nj1) n e x t = ( k i l l + 1 ) mod ( n − j − 1 ) ,那么 f[i][j+1][next]+=f[i][j][k]/m f [ i ] [ j + 1 ] [ n e x t ] + = f [ i ] [ j ] [ k ] / m ,注意当 kill=j k i l l = j 时,不转移(因为主角已经死了)。

代码

#include <cstdio>
#include <algorithm>
#define maxn 55
using namespace std;
double f[maxn][maxn][maxn];
int n, m, a[maxn];
void dp()
{
    int i, j, k, card, kill;
    for(i=1;i<=n;i++)f[i][0][(1-i+n)%n]=1.0;
    for(i=1;i<=n;i++)
        for(j=0;j<n-1;j++)
            for(k=0;k<n-j;k++)
                for(card=1;card<=m;card++)
                {
                    kill=(k+a[card]-1+n-j)%(n-j);
                    if(kill!=0)f[i][j+1][(kill)%(n-j-1)]+=f[i][j][k]/m;
                }
    for(i=1;i<=n;i++)printf("%.2lf%% ",f[i][n-1][0]*100.00);
}
int main()
{
    int i;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)scanf("%d",a+i);
    dp();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值