POJ 2823
#define MAXN 1000003
int a[MAXN];
int n,m;
struct node {
int num,t;
}q[MAXN];
int head,rear;
void add(int num,int i) {
while(head <= rear && q[rear].num <= num) rear--;
rear++;
q[rear].num = num;
q[rear].t = i;
}
void addmin(int num,int i) {
while(head <= rear && q[rear].num >= num) rear--;
rear++;
q[rear].num = num;
q[rear].t = i;
}
int get(int i) {
while(head <= rear && q[head].t < i) head ++;
return q[head].num;
}
void init() {
head = rear = 0;
memset(&q,-127,sizeof(struct node));
int i;
for(i = 0;i<n;i++) {
scanf("%d",&a[i]);
}
for(i = 0;i<m;i++) {
addmin(a[i],i);
}
printf("%d",get(0));
for(i = m;i<n;i++) {
addmin(a[i],i);
printf(" %d",get(i-m+1));
}
puts("");
head = rear = 0;
memset(&q,-127,sizeof(struct node));
for(i = 0;i<m;i++) {
add(a[i],i);
}
printf("%d",get(0));
for(i = m;i<n;i++) {
add(a[i],i);
printf(" %d",get(i-m+1));
}
puts("");
}
int main () {
//FOPEN;
while(~scanf("%d%d",&n,&m)) {
init();
}
}
今天讲的是单调DP,以前没仔细明白过,今天算是明白了,单调队列是一种优化,对连续的一组数据求一段区间的最值问题,既然是区间最值的优化,那应用就广了,比较经典的有-瑰丽华尔兹 。
这个题用单调队列的话确实很裸,但是让人纠结的是WA和TLE,后来我发现我的问题在初始化这里出错了,初始化应该是一个极小值,这样才能保证第一次比较的时候成功赋值!
12 3 1 3 5 7 -1 -1 -1 -1 7 7 7 7 12 4 1 3 5 7 -1 -1 -1 -1 7 7 7 7 12 4 -2000000000 -2 -3 -4 -5 -6 -5 -4 -3 -2 -1 0 12 3 2000000000 -2 -3 -4 -5 -6 -5 -4 -3 -2 -1 0
具体的测试case在这个题后面的discuss那里也有。
但是G++还是超时有木有!
这个单调DP掌握的特别不好,压根不会啊啊啊啊,自己在唔几天吧!

浙公网安备 33010602011771号