MDeath-Kid

- M I T & Y
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

单调队列DP POJ 2823

Posted on 2011-08-08 17:29  MDeath-Kid  阅读(354)  评论(0)    收藏  举报
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掌握的特别不好,压根不会啊啊啊啊,自己在唔几天吧!