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;
    }
    

      

  • 相关阅读:
    如何使用IntelliJ IDEA 14创建基于Maven3的Java Web Project
    一些python语法的合集
    thuwc2019滚粗记
    noip2018总结
    树链剖分
    NOIp2017游记(滚粗之旅)
    使用Redux管理你的React应用
    校招面试中积累的前端问题
    WebService 生成类的命令语句
    Request 请求页面的地址路径获取
  • 原文地址:https://www.cnblogs.com/zj75211/p/8108747.html
Copyright © 2011-2022 走看看