POJ 2823 Sliding Window

POJ_2823

    这个是在接触了单调队列优化后的第一个题目,其实个人感觉单调队列所作的优化就是维护了一个始终保存当前最优解的队列。

    解的合法性是通过队列内各元素的标号的单调性保证的,每次要通过队首删除元素的操作来保证队列内的解是在当前区间内的。

    队首元素的最优性则是由队列内元素值的单调性保证的,每次要通过将队尾不比当前待插入的元素更优的元素删除来保证了队首元素的最优性。

#include<stdio.h>
#include<string.h>
#define MAXD 1000010
int N, K, f[MAXD], d[MAXD], qf[MAXD], nf[MAXD], nd[MAXD], qd[MAXD];
void solve()
{
int i, j, a, qfront, qrear, dfront, drear;
qfront = qrear = dfront = drear = 0;
for(i = 0; i < N; i ++)
{
scanf("%d", &a);
while(qfront < qrear && nf[qfront] <= i - K)
qfront ++;
while(qrear > qfront && qf[qrear - 1] <= a)
qrear --;
qf[qrear] = a;
nf[qrear] = i;
qrear ++;
f[i] = qf[qfront];
while(dfront < drear && nd[dfront] <= i - K)
dfront ++;
while(drear > dfront && qd[drear - 1] >= a)
drear --;
qd[drear] = a;
nd[drear] = i;
drear ++;
d[i] = qd[dfront];
}
printf("%d", d[K - 1]);
for(i = K; i < N; i ++)
printf(" %d", d[i]);
printf("\n");
printf("%d", f[K - 1]);
for(i = K; i < N; i ++)
printf(" %d", f[i]);
printf("\n");
}
int main()
{
while(scanf("%d%d", &N, &K) == 2)
{
solve();
}
return 0;
}


原文地址:https://www.cnblogs.com/staginner/p/2244618.html