专栏文章

CF1469C

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

文章操作

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

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

题解

简单 DP。
可以发现栅栏摆放的地方是一段区间,所以可以设 fi,0f_{i,0} 为第 ii 个栅栏底端的最低高度,fi,1f_{i,1} 为最高高度。
那么 f1,0=f1,1=h1f_{1,0}=f_{1,1}=h_{1}
容易想到 fif_{i} 会被 fi1f_{i-1}hih_{i} 约束。
ii 最高高度,我们在上一个最高的基础上尽量往上搭,则有 fi,1=max(fi1,1+k1,hi+k1)f_{i,1}=\max(f_{i-1,1}+k-1,h_{i}+k-1)
求最低,在上一个最低的基础上尽量往低放,则有 fi,0=min(fi1,0k+1,hi)f_{i,0}=\min(f_{i-1,0}-k+1,h_{i})
然后我们去看是否有与题目约束矛盾的地方。
首先,fn,0f_{n,0} 必须为 hnh_{n}
其次,对于 i[1,n]i \in [1,n]fi,1hif_{i,1} \ge h_{i}fi,0hi+k1f_{i,0} \le h_{i}+k-1
判断这两个条件是否都满足即可。

代码

CPP
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int t;
int n,k;
int h[N],f[N][2];
void solve() {
	memset(f,0,sizeof f);
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",&h[i]);
	f[1][0]=f[1][1]=h[1];
	for(int i=2;i<=n;i++) {
		f[i][1]=min(f[i-1][1],h[i])+k-1;
		f[i][0]=max(f[i-1][0]-k+1,h[i]);
		if(f[i][1]<h[i]||f[i][0]>h[i]+k-1) {puts("NO");return;}
	}
	if(f[n][0]==h[n]) puts("YES");
	else puts("NO");
	return;
}
int main() {
	scanf("%d",&t);
	while(t--) solve();
	return 0;
}

评论

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

正在加载评论...