专栏文章

题解:CF2144C Non-Descending Arrays

CF2144C题解参与者 5已保存评论 4

文章操作

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

当前评论
4 条
当前快照
1 份
快照标识符
@minvwsex
此快照首次捕获于
2025/12/02 09:13
3 个月前
此快照最后确认于
2025/12/02 09:13
3 个月前
查看原文

解题思路

简单 DP 题(甚至可能不算 DP),提供一种容易理解并且好写的做法,复杂度 O(n)O(n)
容易想到fif_i 表示只考虑下标小于等于 iia,ba,b 数组的方案数
然后考虑转移,我们不妨假定前 i1i-1 个元素已经非递减了。当 aiai1a_i\ge a_{i-1} 并且 aibi1a_i\ge b_{i-1} 时,aia_i 换不换均满足条件。同理,当 bib_i 同时满足 biai1b_i\ge a_{i-1}bibi1b_i \ge b_{i-1} 时,那么 bib_i 换或不换也满足条件。如此那么对于下标 ii,我们有换或不换两种方案,转移方程式为: fi=2fi1(aiai1,aibi1,biai1,bibi1)f_i=2f_{i-1}(a_i\ge a_{i-1},a_i\ge b_{i-1},b_i\ge a_{i-1},b_i \ge b_{i-1}) 但如果 aia_ibib_i 至少有一个并不是两个条件都满足,就只有一种选择,不会产生贡献。因为题目保证了“there is at least one good subset”,所以不会存在 aia_ibib_i 两个条件都不满足的情况。
代码
不开 long long 见祖宗。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1002,M=1002,mod=998244353;
#define A (a[i]>=a[i-1])
#define B (b[i]>=b[i-1])
#define C (a[i]>=b[i-1])
#define D (b[i]>=a[i-1])
int T,n,a[N],b[N];
long long f[N];
//bool c[N];

int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		for(int i=1;i<=n;i++){
			scanf("%d",&b[i]);
			f[i]=0;//,c[i]=false;
		}
		f[1]=2;//,c[1]=true;
		for(int i=2;i<=n;i++){
			int x=0;
			x=(A&&B?1:0)+(C&&D?1:0);
			f[i]=(f[i-1]*x)%mod;
		}
		printf("%lld\n",f[n]);
	}
	return 0;
}

没用的小优化

发现 fif_i 仅有的一维 ii 可以滚动掉,将数组 fif_i 优化为一个变量。
代码
不开 long long 见祖宗。
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=1002,mod=998244353;
int T,n,a[N],b[N];
long long ans;

int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		for(int i=1;i<=n;i++) scanf("%d",&b[i]);
		ans=2;
		for(int i=2;i<=n;i++)
			if(a[i]>=a[i-1]&&b[i]>=b[i-1]&&a[i]>=b[i-1]&&b[i]>=a[i-1])
				(ans<<=1)%=mod;
		printf("%lld\n",ans);
	}
	return 0;
}

评论

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

正在加载评论...