Educational Codeforces Round 118 (Rated for Div. 2) D

D. MEX Sequences

题意:给定一个长度为 n n n 的序列,求MEX-correct子序列的个数。定义MEX-correct子序列为:对于数列的某一个子序列 x 1 , x 2 , … , x k x_{1}, x_{2}, \ldots, x_{k} x1,x2,,xk,任意 i ( 1 ≤ i ≤ k ) ∣ x i − MEX ⁡ ( x 1 , x 2 , … , x i ) ∣ ≤ 1 i (1 \leq i \leq k)\left|x_{i}-\operatorname{MEX}\left(x_{1}, x_{2}, \ldots, x_{i}\right)\right| \leq 1 i(1ik)xiMEX(x1,x2,,xi)1
思路
状态定义:
dp[i][0] 表示 mex 值为i,最后一个元素为 i-1 的 MEX-correct子序列个数;
dp[i][1] 表示 mex 值为i,最后一个元素为 i+1 的 MEX-correct子序列个数。
状态转移:
假设有一个已经是 MEX-correct 的序列,现要在末尾添加一个元素 t,则将会有以下三种转移方式:
1.转移到 dp[t+1][0]
状态转移方程:dp[t+1][0]+=dp[t+1][0]+dp[t][0];
2.转移到 dp[t-1][1]
状态转移方程:dp[t-1][1]+=dp[t-1][1]+dp[t-1][0];
3.转移到 dp[t+1][1]
状态转移方程:dp[t+1][1]+=dp[t+1][1];
代码

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=5e5+5;
const int mod=998244353;
int T,n,dp[N][2];

signed main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>T;
	while(T--){
		cin>>n;
		for(int i=0;i<=n+1;++i) dp[i][0]=dp[i][1]=0;
		int t;
		dp[0][0]=1;
		for(int i=1;i<=n;++i) {
			cin>>t; 
			dp[t+1][0]+=dp[t][0]+dp[t+1][0];
			dp[t+1][0]%=mod;
			if(t>=1) {
				dp[t-1][1]+=dp[t-1][1]+dp[t-1][0];
				dp[t-1][1]%=mod;
			}
			dp[t+1][1]+=dp[t+1][1];
			dp[t+1][1]%=mod;
		}
		dp[0][0]-=1;
		int ans=0;
		for(int i=0;i<=n+1;++i) {
			ans+=dp[i][0]+dp[i][1];
			ans%=mod;	
		}
		cout<<ans<<'\n';
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值