poj 2373 单调队列优化背包

时间:2023-03-09 07:37:03
poj 2373 单调队列优化背包

思路:我们用单调队列保存2*b<=i-j<=2*a中的最大值。那么队列头就是最大值,如果队头的标号小于i-2*b的话,就出队,后面的肯定用不到它了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 10000010
#define Maxn 1010
#define Min(a,b) (a)>(b)?(b):(a)
using namespace std;
int dp[],que[],head,rear,interv[];
struct Inter{
int l,r;
int operator<(const Inter &temp) const
{
return l<temp.l;
}
}p[Maxn];
int main()
{
int n,l,i,j,t,a,b;
while(scanf("%d%d",&n,&l)!=EOF)
{
scanf("%d%d",&a,&b);
memset(interv,,sizeof(interv));
for(i=;i<=n;i++)
{
scanf("%d%d",&p[i].l,&p[i].r);
memset(interv+p[i].l+,,(p[i].r-p[i].l-)*sizeof(interv[]));
}
dp[]=;
head=,rear=;
for(i=;i<=l;i++)
{
dp[i]=inf;
j=i-*a;
if(j<) continue;
while(head<=rear&&dp[j]<=dp[que[rear]])
rear--;
if(interv[j])
que[++rear]=j;
if(que[head]<i-*b&&head<=rear)
head++;
if(!interv[i]||(i&)) continue;
if(head<=rear)
dp[i]=dp[que[head]]+;
}
if(dp[l]>=inf) printf("-1\n");
else printf("%d\n",dp[l]);
}
return ;
}