zoukankan      html  css  js  c++  java
  • ●BZOJ 3831 [Poi2014]Little Bird

    题链:

    单调队列优化DP
    定义 F[i] 为到达第i课树的疲劳值
    显然最暴力的转移就是枚举i位置前面的k个位置,找到最优的位置跳过来。
    每一个询问的复杂度 O(KN),最坏达到O(N²)。
    考虑优化:
    设H为高度的话,对于两个转移来源位置x,y(x<y),如何如何判断那个更优呢?
    有如下4种情况:
    1).H[y]≥H[x]且F[y]≤F[x],则任何时候选择y都不会比选择x差,所以从单调队列里去掉x。
    2).H[y]≥H[x]且F[y]>F[x],在 x 由于距离原因而出队之前,选择x都不会比选择y差,所以把y放在队尾。
    3).H[y]<H[x]且F[y]<F[x],则任何时候选择y都不会比选择x差,所以从单调队列里去掉x。
    4).H[y]<H[x]且F[y]≥F[x],在 x 由于距离原因而出队之前,选择x都不会比选择y差,所以把y放在队尾。
    然后用单调队列维护就可以啦,每一个询问的复杂度O(N)。
    代码:
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define MAXN 1000500
    using namespace std;
    int H[MAXN],F[MAXN];
    int N,Q;
    void read(int &x){
    	static int f; static char ch;
    	x=0; f=1; ch=getchar();
    	while(ch<'0'||'9'<ch){if(ch=='-')f=-1;ch=getchar();}
    	while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	x=x*f;
    }
    bool off(int x,int y){
    	if(H[y]>=H[x]){
    		if(F[y]<=F[x]) return 1;
    		else return 0;
    	}
    	else{
    		if(F[y]<F[x]) return 1;
    		else return 0;
    	}
    }
    int main(){
    	static int pos[MAXN],l,r;
    	read(N);
    	for(int i=1;i<=N;i++) read(H[i]);
    	read(Q);
    	for(int q=1,k;q<=Q;q++){
    		read(k); l=1; r=0;
    		F[1]=0; pos[++r]=1;
    		for(int i=2;i<=N;i++){
    			while(l<=r&&i-pos[l]>k) l++;
    			F[i]=F[pos[l]]+(H[pos[l]]<=H[i]);
    			while(l<=r&&off(pos[r],i)) r--;
    			pos[++r]=i;
    		}
    		printf("%d
    ",F[N]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    PHP的资源类型
    windows 配置 apache的多个站点
    php 压缩数据存储
    php统计图类库JpGraph
    php之ThinkPHP的memcached类的修改
    linux 安装报错:pkg-config not found
    Mysql清空表(truncate)与删除表中数据(delete)的区别
    【MySQL】查看MySQL配置文件路径及相关配置
    phper
    http 同步异步请求
  • 原文地址:https://www.cnblogs.com/zj75211/p/8108747.html
Copyright © 2011-2022 走看看