单调队列优化dp——poj2373 经典
经典老题了,其实数据没那么强
/* dp[i]表示覆盖了前[0,i]区间的最优解 dp[i]=min(dp[i-j]) 2A<=j<=2B 直接用单调队列优化 对于奇数坐标,直接忽略就行 */ #include<iostream> #include<queue> #include<cstring> using namespace std; #define N 2000005 #define INF 100000000 int L,n,A,B,l[N],r[N],dp[N]; int main(){ cin>>n>>L>>A>>B; for(int i=1;i<=n;i++){ cin>>l[i]>>r[i]; for(int j=l[i]+1;j<=r[i]-1;j++) dp[j]=INF; } if(L%2 || L<2*A){puts("-1");return 0;} for(int i=2;i<2*A;i+=2)dp[i]=INF; deque<int>q; for(int i=2*A;i<=L;i+=2){ //把i-2B前的元素出队 while(q.size()){ int p=q.front(); if(p<i-2*B){q.pop_front();continue;} else break; } //把dp[i-2A]入队 while(q.size()){ int p=q.back(); if(dp[p]>=dp[i-2*A])q.pop_back(); else break; } q.push_back(i-2*A); if(dp[i]<INF)dp[i]=dp[q.front()]+1; } if(dp[L]<INF)cout<<dp[L]<<'\n'; else cout<<-1<<'\n'; }