We set f [i] f[i]f [ i ] means that the bird is from1 to 11 tree jumps toiiThe minimum cost of i trees.
Then, the naive O (n 2) \operatorname{O}(n^2)O ( n2 ) Thetransformation and equation isf [i] = f [j] + [d [j] ≤ d [i]] f[i]=f[j]+[d[j]\le d[i]]f[i]=f[j]+[ d [ j ]≤d [ i ] ], 其中[d [j] ≤ d [i]] [d [j] \ le d [i]][ d [ j ]≤d [ i ] ] If the conditions in brackets are met, it is1 11 , otherwise0 00
We can find that for x <yx <yx<Y
- 如果 f [ x ] < f [ y ] f[x]<f[y] f[x]<f [ y ] , thenxxx is definitely useless. Because no matter where it is transferred toyyy is no better thanxxx is bad, andxxx will be eliminated first
- Similarly, if f [x] = = f [y] f[x]==f[y]f[x]==f [ y ]并且d [x] ≤ d [y] d [x] \ le d [y]d[x]≤d [ y ] , thenxxx must be useless
Then, we can use monotonic queue maintenance, the total time complexity is O (n) \operatorname{O}(n)O ( n )
#include<cstdio>
#include<iostream>
#include<deque>
#include<cstring>
using namespace std;
const int Maxn=1000000+10;
int a[Maxn],f[Maxn];
int n,m,k;
deque <int> q;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
void push(int pos)
{
while(q.size())
{
int x=q.back();
if(f[x]<f[pos] || f[x]==f[pos] && a[x]>a[pos])break;
q.pop_back();
}
q.push_back(pos);
}
void pop(int i)
{
while(q.size())
{
if(q.front()>=i-k)break;
q.pop_front();
}
}
int main()
{
// freopen("in.txt","r",stdin);
n=read();
for(int i=1;i<=n;++i)
a[i]=read();
m=read();
while(m--)
{
k=read();
q.push_back(1);
for(int i=2;i<=n;++i)
{
pop(i);
int j=q.front();
f[i]=f[j];
if(a[j]<=a[i])++f[i];
push(i);
}
printf("%d\n",f[n]);
q.clear();
memset(f,0,sizeof(f));
}
return 0;
}