今天一天基本都在做题……
然后又学了一下单调队列。
下面附单调队列的最基础的题:
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
8 3 1 3 -1 -3 5 3 6 7
-1 -3 -3 -3 3 3 3 3 5 5 6 7
这算是单调队列的另一种描述了。
想取得的最值一直出现在队首。用head控制队首。只需要保存前k-1个的最值。
所以当队首的元素的下标小于i-k+1的时候,就说明队首的元素对于求f(i)已经没有意义了。所以当index[队首元素]<i-k+1时,将队首元素删除。
单调队列与普通队列的区别也就在于需要保存元素位置。
然而现在队首元素位置的移动……还是有点晕。
附这个题的代码:
//1009:Sliding Window
/*单调队列问题*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <string>
#define MAX 1000000
using namespace std;
int num[MAX];
int q[MAX];
int I[MAX];
int n,k;
void getmin()
{
int head = 1,tail = 0;
for (int t = 1; t < k; t++)
{
while (head <= tail && q[tail] >= num[t])
tail--;
tail++;
q[tail] = num[t];
I[tail] = t;
}
for (int t = k; t <= n; t++)
{
while (head <= tail && q[tail] >= num[t])
tail--;
tail++;
q[tail] = num[t];
I[tail] = t;
while (I[head] <= t - k)
head++;
cout << q[head] << " ";
}
}
void getmax()
{
int head = 1,tail = 0;
for (int t = 1; t < k; t++)
{
while (head <= tail && q[tail] <= num[t])
tail--;
tail++;
q[tail] = num[t];
I[tail] = t;
}
for (int t = k; t <= n; t++)
{
while (head <= tail && q[tail] <= num[t])
tail--;
tail++;
q[tail] = num[t];
I[tail] = t;
while (I[head] <= t - k)
head++;
cout << q[head] << " ";
}
}
int main()
{
scanf("%d%d", &n,&k);
for (int i = 1; i <= n; i++)
scanf("%d",&num[i]);
getmin();
printf("\n");
getmax();
printf("\n");
return 0;
}
然后现在在做一个二分题……先去把这个题A掉……感觉很水的一道题
明天继续学习。。。单调队列。。。