思路:从每个界点从前往后扫描,没有限制为前面值+1,否则取和限制的值中的最小值,在从后往前扫一遍,同样的操作,最终取两次扫描相同下标的最小值,在这里面找最大值
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 1e5 + 10;
const int INF = 1e7;
using namespace std;
int limit[maxn];
int l[maxn], r[maxn];
void init() {
memset(limit, -1, sizeof(limit));
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
}
int main() {
int n, m, t;
scanf("%d", &t);
while(t--) {
init();
scanf("%d %d", &n, &m);
while(m--) {
int f, t;
scanf("%d %d", &f, &t);
limit[f] = t;
}
limit[1] = 0;
int ans1 = 0, ans2 = INF;
for(int i = 1; i <= n; i++) {
ans1++;
if(limit[i] >= 0) ans1 = min(limit[i], ans1);
l[i] = ans1;
}
for(int i = n; i >= 1; i--) {
ans2++;
if(limit[i] >= 0) ans2 = min(ans2, limit[i]);
r[i] = ans2;
}
int ans = 0;
for(int i = 1; i <= n; i++) {
ans = max(ans, min(l[i], r[i]));
}
printf("%d\n", ans);
}
return 0;
}
本文介绍了一种通过双向扫描求解区间内数值受限制情况下的最优解算法。该算法首先初始化数组并设置边界条件,接着从前向后扫描更新当前可达的最大值,并与限制值进行比较取最小值;随后从后向前再次扫描,重复类似操作。最后,在两次扫描结果中寻找相同下标处的最小值来确定最大可行解。
4618

被折叠的 条评论
为什么被折叠?



