专栏文章
题解:CF2061C Kevin and Puzzle
CF2061C题解参与者 2已保存评论 2
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @miqemf7y
- 此快照首次捕获于
- 2025/12/04 03:32 3 个月前
- 此快照最后确认于
- 2025/12/04 03:32 3 个月前
题意
组数据。
个人站成一排,第 个人会告诉你他的左边有 个说谎者。
每个人有两种身份,诚实者和说谎者,诚实者一定会说真话,说谎者可能会说真话,也可能会说假话。
说谎者之间不能相邻。
现在问你游戏一共有多少种不同的情况。答案对 取余。
思路
考虑动态规划,我们可以用一个数组 来统计答案。其中 用来统计第 个人是诚实者/说谎者产生的贡献。
继续考虑初始化,我们可以初始化第 个人的,因为他只有是诚实者或说谎者两种可能。如果他是诚实者,那么就是 种情况,也就是说真话,即 ,如果他是说谎者,那么就要判断他说的是不是真话,我们可以判断 是否为 ,因为他左边已经没有人了。所以初始化为 。
接下来考虑转移方程,如果第 个人是说谎者,那么第 个人绝对不可能是说谎者,即 。
如果第 个人不是说谎者,那么就需要继续考虑。
- 第 个人是说谎者。那么第 个就一定不是说谎者。这需要满足 ,因为他们之间夹了一个说谎者。即 。
- 第 个人是诚实者。那么就需要满足 ,因为他们都是诚实者,所以不可能有差别。即 。
最终的答案为 。注意多测清空。
代码
CPP#include<bits/stdc++.h>
using namespace std;
const int mod=998244353,N=2e5+7;
int n,a[N],dp[N][2],t;
int main()
{
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
dp[1][0]=1;
if(a[1]==0)dp[1][1]=1;
else dp[1][1]=0;
for(int i=2;i<=n;i++){
dp[i][0]=dp[i-1][1];
dp[i][1]=0;
if(a[i]==a[i-1])dp[i][1]=(dp[i][1]+dp[i-1][1])%mod;
if(a[i]-1==a[i-2])dp[i][1]=(dp[i][1]+dp[i-1][0])%mod;
}
cout<<(dp[n][0]+dp[n][1])%mod<<endl;
}
return 0;
}
相关推荐
评论
共 2 条评论,欢迎与作者交流。
正在加载评论...