专栏文章

题解:CF2061C Kevin and Puzzle

CF2061C题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq6fycl
此快照首次捕获于
2025/12/03 23:43
3 个月前
此快照最后确认于
2025/12/03 23:43
3 个月前
查看原文
可以发现样例解释出现红蓝双色,一眼dp
发现题目很套路,可以设 dpi,0/1dp_{i,0/1} 代表在前 i1i - 1 个人已经确定的情况下,第 ii 个人说真话 (00)或者假话(11)。
可以发现,当这个人说假话的时候,前一个人一定说真话,后一个人也是,但由于递推,只考虑前,可得:
dpi,1=dpi1,0dp_{i,1} = dp_{i - 1,0}
那当这一个人说真话的时候,前一个人可能说真话也可能说假话,但是如果是说假话,大前个人一定说真话(因为相邻两个人不同时说假话),可得:
dpi,0={dpi1,0if ai=ai1dpi1,1if ai=ai2+1dp_{i,0} = \begin{cases} dp_{i - 1,0} & \text{if } a_i = a_{i - 1}\\ dp_{i - 1,1} & \text{if } a_i = a_{i - 2} + 1\\ \end{cases}
由于第 nn 个人有可能说真话也有可能说假话,所以答案为 dpn,0+dpn,1dp_{n,0} + dp_{n,1}109+710^9+7 取模的结果。
注意随时取模。
CPP
#include <bits/stdc++.h>
using namespace std;
#define int long long
int dp[200010][2],a[200010];
signed main(){
    int t;
    cin >> t;
    while(t--){
        memset(dp,0,sizeof dp);
        int n;
        cin >> n;
        for(int i = 1;i <= n;i++) cin >> a[i];
        dp[1][1] = 1;
        if(a[1]) dp[1][0] = 0;
        else dp[1][0] = 1;
        for(int i = 2;i <= n;i++){
            dp[i][1] = dp[i - 1][0];
            if(a[i] == a[i - 1]) dp[i][0] = dp[i - 1][0];
            if(a[i] == a[i - 2] + 1) dp[i][0] += dp[i - 1][1];
            dp[i][1] %= 998244353;
            dp[i][0] %= 998244353;
        }
        cout << (dp[n][0] + dp[n][1]) % 998244353 << '\n';
    }
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...