1. 程式人生 > >little bird

little bird

入隊 space bsp spa 單調性 -- int 技術分享 如果

技術分享

LITTLE BIRD

Bzoj 3831

相對而言是一道比較簡單的DP,不過它需要用單調隊列優化。首先是樸素On2,

if(d[j]>f[i])

f[i]=min(f[i],f[j]);

else

f[i]=min(f[i],f[j]+1);

f[i]表示從1i需要的最少代價

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 
13
int 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 41
f[i]=min(f[i],f[j]+1); 42 43 } 44 45 } 46 47 cout<<f[n]; 48 49 return 0; 50 51 }

然後是單調隊列優化,On)的復雜度,對於兩個位置ijij之後,如果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