• C. Card Game(dp&组合数)


    C. Card Game(dp&组合数)

    1.平局只有一种情况。

    • 首先最大肯定在后手,不然先手直接赢。
    • 然后次大肯定在先手 ,不然后手出牌的时候直接赢。
    • 然后第三大肯定在先手,不然 先手若出次大,后手出最大接第三大,或者先手出其他,后手出第三大接最大。。
    • 依此类推。

    因为总情况一定 C ( n , n 2 ) C(n,\dfrac{n}{2}) C(n,2n)

    因此只需要计算先手赢的情况即可算出另一种情况。

    考虑dp,利用前四大转移。

    如果先手有最大直接赢,贡献是 C ( i − 1 , 2 i − 1 ) C(i-1,\dfrac{2}{i}-1) C(i1,i21)

    然后考虑后手有最大的情况,那么显然先手必须有次大,不然会输。

    已知先手次大,后手有最大。根据上面的情况可知第三大肯定也在先手。

    接下来讨论论第四大情况,若在先手。先手可以先打次大,然后后手打最大,后手再打其他,先手打第三大,然后再打第四大赢。贡献为 C ( i − 4 , i 2 − 1 ) C(i-4,\dfrac{i}{2}-1) C(i4,2i1)

    然后是第四大在后手,那么先手会先打第三大,然后后手最大,然后后手会打第四大来消耗先手的次大,那么转移成了 d p ( i z − 4 ) dp(iz-4) dp(iz4)的情况。

    因此可以dp。

    预处理组合数。

    时间复杂度: O ( n 2 ) O(n^2) O(n2)

    #include 
    #define ll long long
    using namespace std;
    const int N = 65, mod = 998244353;
    
    int c[N][N];
    int f[N];
    
    void solve()
    {
        int n;
        cin >> n;
    
        //组合数常见写法,从i中选j个
        for (int i = 0; i < N; i++){
            for (int j = 0; j <= i; j++){
                if (!j) c[i][j] = 1;
                else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
            }
        }
    
        f[2] = 1;
        f[4] = 3;
        for (int i = 6; i <= n; i += 2){
            f[i] = ((c[i - 1][i / 2 - 1] + c[i - 4][i / 2 - 1]) % mod + f[i - 4]) % mod;
        }
    	
    	//每次都要取模,不然就会溢出
        cout << f[n] << ' ' << (c[n][n / 2] - f[n] - 1 + mod) % mod << ' ' << 1 << endl;
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--){
            solve();
        }
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    北斗导航 | SINS/GPS超紧组合系统完好性监测算法(代码后续添加)
    quartz笔记
    mybatis项目启动报错:reader entry: ���� = v
    GOOGLE SRE 运维模式解读
    1375. 二进制字符串前缀一致的次数-前序遍历法
    C++面经之继承|菱形继承和虚拟继承|一些关于继承的笔试面试题
    对Docker基础镜像的思考,该不该选择alpine
    ArcGIS Pro导出布局时去除在线地图水印
    36岁,大龄剩男,2024上半年总结......
    坐月子真不能洗头吗?
  • 原文地址:https://blog.csdn.net/weixin_45750972/article/details/127925486