刚刚学习了单调队列,来练习一道,等会去试试多重背包。
如题:http://poj.org/problem?id=2823
Time Limit: 12000MS | Memory Limit: 65536K | |
Total Submissions: 47025 | Accepted: 13585 | |
Case Time Limit: 5000MS |
Description
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.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
Source
思路:单调队列也就是在一个队列中维护一个单调不减或单调不增的序列,每次用的时候从头取出来。插入的时候在尾部,并在头部删除无效的值,具体百度。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int a[1000005];
typedef pair<int,int>P;
int top1,rear1,top2,rear2;
P que1[1000005]; //单调减
P que2[1000005]; //单调加
void insert(int x,int i)
{
while(rear1>top1&&x<que1[rear1-1].first)
rear1--;
que1[rear1++]=P(x,i);
while(rear2>top2&&x>que2[rear2-1].first)
rear2--;
que2[rear2++]=P(x,i);
}
int main()
{
// freopen("C:\\1.txt","r",stdin);
int n,k;
cin>>n>>k;
int i;
for(i=1;i<=n;i++)
cin>>a[i];
top1=rear1=0;
top2=rear2=0;
vector<int>res1;
vector<int>res2;
for(i=1;i<=k;i++)
{
insert(a[i],i);
}
for(i=k+1;i<=n;i++)
{
res1.push_back(que1[top1].first);
res2.push_back(que2[top2].first);
insert(a[i],i);
while(que1[top1].second<i-k+1)
top1++;
while(que2[top2].second<i-k+1)
top2++;
}
res1.push_back(que1[top1].first);
res2.push_back(que2[top2].first);
for(i=0;i<res1.size();i++)
{
printf("%d%c",res1[i],i==res1.size()-1?'\n':' ');
}
for(i=0;i<res2.size();i++)
{
printf("%d%c",res2[i],i==res2.size()-1?'\n':' ');
}
return 0;
}