• 单调队列优化DP || [Poi2014]Little Bird || BZOJ 3831 || Luogu P3572


    题面:[POI2014]PTA-Little Bird

    题解:

    N<=1e6 Q<=25
    F[i]表示到达第i棵树时需要消耗的最小体力值
    F[i]=min(F[i],F[j]+(D[j]>=D[i])) (j>=i-K)
    使用单调队列维护
    越小的越优,在写单调队列时,让F值最小的数越前
    因为F[i]-F[j]最多等于1
    然后如果F值相同,则D越大的越优,因为D越大,后面不用+1的概率越大
    大概就是这样

    代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #define min(a,b) ((a)<(b)?(a):(b))
     4 #define max(a,b) ((a)>(b)?(a):(b))
     5 using namespace std;
     6 int rd(){
     7     int x=0; char c=getchar();
     8     while(c<'0'||c>'9') c=getchar();
     9     while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    10     return x;
    11 }
    12 const int maxn=1e6+5,maxq=30,inf=1<<30;
    13 int N,D[maxn],F[maxn],Q,K,f1,f2;
    14 int que[maxn];
    15 int main(){
    16     N=rd();
    17     for(int i=1;i<=N;i++) D[i]=rd();
    18     Q=rd();
    19     while(Q--){
    20         f1=1;f2=0;
    21         que[++f2]=1;
    22         K=rd();
    23         for(int i=2;i<=N;i++){
    24             while(f1<=f2 && que[f1]<i-K) f1++;
    25             if(f1<=f2) F[i]=F[que[f1]]+(D[que[f1]]<=D[i]);
    26             while(f1<=f2 && F[i]<F[que[f2]]) f2--;
    27             while(f1<=f2 && F[i]==F[que[f2]] && D[i]>D[que[f2]]) f2--;
    28             que[++f2]=i;
    29         }
    30         printf("%d
    ",F[N]);
    31     }
    32     return 0;
    33 } 

    By:AlenaNuna

  • 相关阅读:
    99乘法表的几种实现方法
    log4net使用(包括单个文件和按日期生成多个文件)
    c# 压缩文件
    寻找Windows下MySQL的错误日志
    MySQL 索引
    java hashCode 作用
    springMVC swagger2
    ConcurrentHashMap原理分析(1.7与1.8)
    国产烂片深度揭秘
    Practice| 类型转换| 逻辑运算
  • 原文地址:https://www.cnblogs.com/AlenaNuna/p/11559673.html
Copyright © 2020-2023  润新知