链接:http://poj.org/problem?id=2373
很明显的DP问题,但是如果利用n^2的算法,肯定会超时,dp[i]表示覆盖到i时的最优值,显然i是偶数,而根据题目描述可以知道,对于一个点i因为每一个覆盖的范围可以调节,而且有最大值和最小值,那么这个解的最优子结构肯定在一个区间里面,这样就可以考虑利用单调队列进行优化,单调队列记录的是在从一个点i开始的往前2*b-2*a的单调递增序列。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #define N 1000005 6 #define inf 1<<30 7 using namespace std; 8 int que[N]; 9 int id[N]; 10 int pos[N]; 11 int dp[N]; 12 struct node 13 { 14 int l,r; 15 }; 16 node cow[N]; 17 int cmp(const void *a,const void *b) 18 { 19 node *c=(node *)a; 20 node *d=(node *)b; 21 if(c->l!=d->l) 22 return c->l-d->l; 23 else 24 return d->r-c->r; 25 } 26 int max(int a,int b) 27 { 28 return a>b?a:b; 29 } 30 int min(int a,int b) 31 { 32 return a<b?a:b; 33 } 34 int main() 35 { 36 int n,L,a,b,i,j; 37 int f1,r1,p; 38 scanf("%d%d",&n,&L); 39 scanf("%d%d",&a,&b); 40 for(i=1;i<=n;i++) 41 scanf("%d%d",&cow[i].l,&cow[i].r); 42 qsort(cow+1,n,sizeof(node),cmp); 43 j=2; 44 for(i=2;i<=n;i++) 45 { 46 if(cow[j-1].l<=cow[i].l&&cow[j-1].r>cow[i].l) 47 { 48 cow[j-1].l=min(cow[j-1].l,cow[i].l); 49 cow[j-1].r=max(cow[j-1].r,cow[i].r); 50 } 51 else 52 { 53 cow[j].l=cow[i].l; 54 cow[j++].r=cow[i].r; 55 } 56 } 57 n=j; 58 id[0]=0; 59 f1=r1=0; 60 pos[0]=0; 61 p=1; 62 for(i=1;i<=L;i++) 63 dp[i]=inf; 64 for(i=2;i<=L;i+=2) 65 { 66 if(p<n&&cow[p].r<=i) 67 p++; 68 if(p<n&&cow[p].l<i) 69 continue; 70 while(f1<=r1&&i-id[f1]>2*b) 71 f1++; 72 if(f1>r1||i-id[f1]<2*a) 73 dp[i]=inf; 74 else 75 dp[i]=pos[f1]+1; 76 while(f1<=r1&&pos[r1]>dp[i]) 77 r1--; 78 pos[++r1]=dp[i]; 79 id[r1]=i; 80 } 81 if(dp[L]>=inf) 82 printf("-1\n"); 83 else 84 printf("%d\n",dp[L]); 85 return 0; 86 }