4325. 【NOIP2015提高组Day1】斗地主

本文解析了NOIP2015提高组Day1的“斗地主”题目,通过预处理不同牌型组合的最优出牌策略,采用深度优先搜索(DFS)方法,并结合顺子情况的递归求解,实现了复杂牌局的高效求解。

4325. 【NOIP2015提高组Day1】斗地主

https://jzoj.net/senior/#main/show/4325
15年提高组的题,看到标题我吓了一跳,但细细分析来,还是可以做的。

过流程(题目描述):
这里写图片描述
大致是说给你一些牌,按照上述出牌方式,最少几步可以出完所有牌。

一开始就想到了很平常的方法——dfs,但我们发现直接暴力会T,于是,观察数据:n是固定的,所以这题会有很多状态是一样的,我们便自然的想到了预处理。

首先看,除顺子外,其他出牌方式对点数都没有要求,只对数量有要求,所以大致的思路就是先预处理没有顺子的情况的出牌步数,然后暴力求顺子的状况,O(1)求解。

我们设f[i][j][k][l]表示还剩i种牌有4张,j种牌有3张,k种牌有2张,l种牌有1张的最小出牌步数。
于是就有除顺子外的9种转移:

int did(int a,int b,int c,int d)
{
    int ss=a+b+c+d;
    if (d>=1)
        ss=min(ss,f[a][b][c][d-1]);
    if (b>=1 && c>=1)
        ss=min(ss,f[a][b-1][c-1][d]);
    if (b>=1 && d>=1)
        ss=min(ss,f[a][b-1][c][d-1]);
    if (c>=1)
        ss=min(ss,f[a][b][c-1][d]);
    if (b>=1)
        ss=min(ss,f[a][b-1][c][d]);
    if (a>=1)
        ss=min(ss,f[a-1][b][c][d]);
    if (a>=1 && d>=2)
        ss=min(ss,f[a-1][b][c][d-2]);
    if (a>=1 && c>=2)
        ss=min(ss,f[a-1][b][c-2][d]);
    if (a>=1 && c>=1)
        ss=min(ss,f[a-1][b][c-1][d]);
}
......
{
    f[0][0][0][0]=0;
    for (i=0;i<=n;i++)
        for (j=0;j<=n;j++)
            for (k=0;k<=n;k++)
                for (l=0;l<=n;l++)
                    f[i][j][k][l]=min(did(i,j,k,l)+1,f[i][j][k][l]);
}

在此之后,我们可以递归1~3顺子的情况,每一种状态更新答案即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值