其他分享
首页 > 其他分享> > 【CF487B】Strip 题解

【CF487B】Strip 题解

作者:互联网

Solution

没想到这道题就个 RMQ + 简单 dp。从小到大遍历 \(l\) 到 \(n\),对于每个确定的区间右端点 \(i\),记 \(f_i\) 表示 \([1,i]\) 中最少能分成几段。那么显然,\(f_i = \min(f_j|j\in[1,i - l + 1]) + 1\)。当然,前提是 \(f_j\) 可被分为若干段。

下面先贴上代码,后面会详讲优化及其原因。

(看见前面几篇题解都没有提到这个优化的具体原因。)

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

#define rep(i, a, b) for(register int i = a; i <= b; ++i)
#define per(i, a, b) for(register int i = a; i >= b; --i)
typedef long long ll ;
const int inf = 2147483647;
inline int rd(){
    int x = 1, s = 0; char ch = getchar();
    while(ch < '0' or ch > '9'){if(ch == '-') x = -1; ch = getchar();}
    while(ch >= '0' and ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return x * s;
}
inline void wr(int x){
    if(x < 0) putchar('-'), x *= -1;
    if(x > 9) wr(x / 10);
    putchar(x % 10 + '0');
}
const int maxn = 1e5 + 5;
//----------------------------------//
int n, l, s;
int mn[maxn][30], mx[maxn][30], rec;
int lg[maxn], f[maxn];

inline void pre(){
	for(int i = 1; (1 << i) <= n; ++i)
		for(int j = 1; j + (1 << i) - 1 <= n; ++j)
			mn[j][i] = min(mn[j][i - 1], mn[j + (1 << (i - 1))][i - 1]),
			mx[j][i] = max(mx[j][i - 1], mx[j + (1 << (i - 1))][i - 1]);
}

inline int chck(int L, int R){
	int k = 0;
	while((1 << (k + 1)) <= R - L + 1) k += 1;
	int mi = min(mn[L][k], mn[R - (1 << k) + 1][k]);
	int ma = max(mx[L][k], mx[R - (1 << k) + 1][k]);
	return ma - mi;
}
	
int main(){
	n = rd(), s = rd(), l = rd();
	rep(i, 1, n) f[i] = inf, mx[i][0] = mn[i][0] = rd();
	pre();
	rep(i, l, n){
		while(i - rec + 1 > l and ((f[rec] == inf) or (chck(rec + 1, i) > s)))
			rec += 1;
		if(i - rec + 1 > l) f[i] = min(f[i], f[rec] + 1);
	}
	if(f[n] != inf) wr(f[n]);
	else wr(-1);
}

在上面的代码中可以看到具体实现。这里有个优化:为什么每次枚举到一个新的右端点,不需要从头再选一次 \(f\) 值最小的左端点 \(j\) 呢?这时候要注意到一个很重要的性质:对于一个区间 \([p,q]\),若将 \(q+1\) 这个节点也加进来,它要么对这个区间的极差没有影响,要么只会将这个极差变得更大。所以,若是一个左端点 \(j\),满足区间 \([j,i-1]\) 的极差大于 \(s\),那么区间 \([j,i]\) 的极差也必定大于 \(s\)(其他情况同理)。同时,左端点 \(j\) 越往右,\(f_j\) 只会不变或更大。

综上,我们只需要继续上一个枚举的 \(i\) 的左端点的位置往后枚举新的左端点,并且取最左边的合法左端点即可。


感谢阅读。

辛苦管理员审核,如有问题烦请指出。

标签:ch,int,题解,CF487B,极差,maxn,端点,Strip,rec
来源: https://www.cnblogs.com/gsn531/p/16496522.html