zoukankan      html  css  js  c++  java
  • 【题解】PTA-Little Bird

    Link

    单调队列板子。

    题目大意:一个点可以由距离它不超过(k)的点跳过来,如果那个点比它高就不需要花费体力,否则花费(1)的体力。问走到(n)的最小体力,多组询问。

    显然的转移方程,设计(dp_i)表示跳到(i)的最小体力,枚举(i-k o i-1)转移即可。

    这东西显然(O(n)),复杂度爆炸。

    我们用单调队列优化一波,维护的是一个区间具有单调性的下标。

    我们每次插入一个点到队尾,即序列右端,插入之前,看看尾部的数:如果这个数的(dp)值大于要插入的这个数或者是(dp)值相等但高度要小,则把它踢出去。

    那么这样我们维护了一个从左到右单调递增的一个(dp)序列。每次更新找最左端那个下标对应(dp)值更新即可。

    实现上使用的双端队列,这题比较卡常,需要(O_2).复杂度是(O(qn).)

    #include<bits/stdc++.h>
    using namespace std;
    
    deque<int>q;
    int n,Q,a[2000010];
    int k,dp[2000010];
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)scanf("%d",a+i);
    	scanf("%d",&Q);
    	for(;Q;--Q){
    		scanf("%d",&k);q.clear();
    		q.push_back(1);
    		for(int i=2;i<=n;++i){
    			while(!q.empty()&&i-q.front()>k)q.pop_front();
    			if(a[q.front()]>a[i])dp[i]=dp[q.front()];
    			else dp[i]=dp[q.front()]+1;
    			while(!q.empty()&&(dp[q.back()]>dp[i]||(dp[q.back()]==dp[i]&&a[q.back()]<=a[i])))q.pop_back();
    			q.push_back(i);
    		}
    		printf("%d
    ",dp[n]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Laravel中如何将单个routes.php分割成多个子文件
    PHP中“==”运算符的安全问题
    一些需要禁用的PHP危险函数
    使用PHP QR Code生成二维码
    gulp详细入门教程
    h5+分享到微信、朋友圈代码示例
    学习地址
    关于this 方法中套方法中找 立即执行的问题 等问题
    判断条件问题是否存在
    jsp 基础语法
  • 原文地址:https://www.cnblogs.com/h-lka/p/12708517.html
Copyright © 2011-2022 走看看