P3572 [POI2014] PTA-Little Bird

/*
第i只鸟在第j棵树 可以飞到j+1~j+ki棵 若后一棵树更高 花费1 问第i只鸟 最小花费
f[i]飞到第i棵树 最小花费 
f[i]=min(a[j]>a[i]? f[j]:f[j]+1)  i-ki<=j<=i-1

单调队列维护f[i] 若a[i]大且f[i]小 于 a[j] j 出列 
*/
/*
9
4 6 3 6 3 7 2 6 5
2
2
5

2
1

*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
typedef long long ll;
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e6 +10;
const int mod=998244353;
const int inf=0x3f3f3f3f;

int f[maxn],a[maxn],n,m,x,q[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    cin>>m;
    
    while(m--){
        cin>>x;
        int tail=0,head=1; q[++tail]=1; //f[1]=0;
        for(int i=2;i<=n;i++){
            while(head<=tail&&i-q[head]>x) head++;
            f[i]= a[i]<a[q[head]]? f[q[head]]:f[q[head]]+1;
            
            while(head<=tail&&(f[q[tail]]>f[i]||(f[q[tail]]==f[i]&&a[q[tail]]<=a[i]))) tail--;
            q[++tail]=i;
            
        }
        cout<<f[n]<<'\n';
    }
   
    return 0;
}

 

posted @ 2023-12-14 04:49  JMXZ  阅读(3)  评论(0)    收藏  举报