Flipping Game

PTA | 程序设计类实验辅助教学平台 (pintia.cn)icon-default.png?t=N7T8https://pintia.cn/problem-sets/91827364500/exam/problems/91827370509?type=7&page=0题意 

        给定两个长度为n的字符串,代表初始灯泡状态和目标灯泡状态,经过k个回合,按下m个不同的开关,问有多少种方案能使灯泡从初始状态到目标状态

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <deque>
#include <cstdlib>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <unordered_map>

using namespace std;

const int mod = 998244353;

int t;
int n, k, m, ans;
char start[105], target[105];
long long C[105][105], dp[105][105];

int main()
{
    C[0][0] = C[1][0] = C[1][1] = 1;//初始化组合数数组
    for(int i = 2;i < 105;i ++ )
    {
        C[i][0] = C[i][i] = 1;

        for(int j = 1;j < i;j ++ )
        {
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
        }

    }

    scanf("%d", &t);

    while(t -- )
    {
        ans = 0;

        scanf("%d %d %d", &n, &k, &m);
        scanf("%s %s", start, target);

        for(int i = 0;i < k;i ++ )
        {
            for(int j = 0;j <= 105;j ++ )
            {
                dp[i][j] = 0;
            }
        }

        int num = 0;//记录初始灯状态与目标灯状态相差个数

        for(int i = 0;i < n;i ++ )
        {
            if(start[i] != target[i])
            {
                num ++;
            }
        }

        //dp[i][j]代表在进行第i次操作后,仍有j个灯泡状态与目标状态不符
        dp[0][num] = 1;

        for(int i = 0;i < k;i ++ )
        {
            for(int j = 0;j <= n;j ++ )
            {
                if(dp[i][j])
                {
                    for(int k = 0;k <= j;k ++ )
                    {
                        if(n - j >= m - k)
                        {
                            int to = j - k + m - k;
                            //C[j][k]表示在j个不符灯泡中挑选k个灯泡的情况数 C[n - j][m - k]表示在符合的灯泡中挑选m - k的情况数
                            dp[i + 1][to] = (dp[i + 1][to] + C[j][k] * C[n - j][m - k] % mod * dp[i][j] % mod) % mod;
                        }
                    }
                }
            }
        }
        printf("%lld\n", dp[k][0]);
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Miracleresss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值