little bird
阿新 • • 發佈:2017-08-05
入隊 space bsp spa 單調性 -- int 技術分享 如果
LITTLE BIRD
Bzoj 3831
相對而言是一道比較簡單的DP,不過它需要用單調隊列優化。首先是樸素O(n2),
if(d[j]>f[i])
f[i]=min(f[i],f[j]);
else
f[i]=min(f[i],f[j]+1);
f[i]表示從1到i需要的最少代價
K很大時會很慢
1 #include<bits/stdc++.h> 2 3 #define INF 9999999 4 5 using namespace std; 6 7 int n,k; 8 9 int f[1000000]; 10 11 int d[1000000]; 12 13int main() 14 15 { 16 17 cin>>n>>k; 18 19 memset(f,INF,sizeof(f)); 20 21 f[1]=0; 22 23 for(int i=1;i<=n;i++) 24 25 cin>>d[i]; 26 27 for(int i=1;i<=n;i++) 28 29 { 30 31 for(int j=i-k;j<i;j++) 32 33 { 34 35 if(d[j]>d[i]) 36 37 f[i]=min(f[i],f[j]); 38 39 else 40 41f[i]=min(f[i],f[j]+1); 42 43 } 44 45 } 46 47 cout<<f[n]; 48 49 return 0; 50 51 }
然後是單調隊列優化,O(n)的復雜度,對於兩個位置i、j,i在j之後,如果f[i]<f[j],直接拋棄j,如果f[i]==f[j],那再h[i]>=h[j],也是拋棄j,即tail--,最後i入隊。隊列的單調性是單調遞增的,每次取隊首就可以了。
優化過後,果然很快。
#include<bits/stdc++.h> using namespace std; int top,tail,q[1000001]; int f[1000001]; int n,k; int d[1000001]; bool cmp(int f1,int h1,int f2,int h2) { return f1==f2?h1>=h2:f1<f2; } int main() { cin>>n>>k; for(int i=1;i<=n;i++) cin>>d[i]; q[top=tail=1]=1; for(int i=2;i<=n;i++) { while(top<=tail&&i-top>k)top++; f[i]=f[q[top]]+(d[i]>=d[q[top]]?1:0); while(top<=tail&&cmp(f[i],d[i],f[tail],d[tail]))tail--; q[++tail]=i; } cout<<f[n]; return 0; }
little bird