zoukankan      html  css  js  c++  java
  • P3572 [POI2014]PTA-Little Bird

    Link

    题意

    (n) 棵树,第 (i) 棵树的高度是 (d_i)

    ( exttt{HLY}) 要去第 (n) 棵树。

    如果 ( exttt{HLY}) 在第 (i) 棵树,那么他可以跳到第 (i+1,i+2,cdots,i+k) 棵树。

    如果她跳到一棵不矮于当前树的树,那么他的劳累值会 (+1);否则不会。

    ( exttt{HYL}) 到达第 (n) 棵树的最小劳累值。


    考试的时候想到了可以用单调队列来优化,结果却 yy 出了一种错误的想法,维护最大值和次大值。

    结果,最后只能交了 (n^2) 的暴力滚粗。

    首先, (n^2) 的暴力dp,肯定都比较容易想到。

    (f[i] = min(f[i], f[j] + (h[i] >= h[j]) ) 其中 j in {1,i-k})

    这个就可以联想到单调队列优化,因为是求 (i-k,i) 的区间最小值。

    但这个高度就处理起来很麻烦。

    我们考虑什么时候是不优的。

    • (f[q[tail]] < f[i]) ,也就是说 (f[q[tail]] >= f[i] + 1) ,我们直接可以把 (q[tail]) 出队。
    • 就算 (f[q[tail] + 1) 也不会比 (f[i]) 更优。
    • (f[q[tail]] = f[i]) 这时候就要仔细想想了,如果 (f) 数组的值相同的话,我们要尽可能的让高度大的留下来,因为这样后面转移时可以承接更多的树,也是就会
    • 使加一的次数变小很多。

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int n,t,k,head,tail,h[1000010],f[1000010],q[1000010];
    inline int read()
    {
    	int s = 0,w = 1; char ch = getchar();
    	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
    	while(ch >= '0' && ch <= '9'){s =s * 10+ch - '0'; ch = getchar();}
    	return s * w;
    }
    int main()
    {
    //	freopen("t4.in","r",stdin);
    //	freopen("t4.out","w",stdout);
    	n = read();
    	for(int i = 1; i <= n; i++) h[i] = read();
    	t = read();
    	while(t--)
    	{
    		k = read();
    		memset(f,0x3f,sizeof(f));
    		head = 1,tail = 0; 
    		f[1] = 0; q[++tail] = 1;//先把一号点入队
    		for(int i = 2; i <= n; i++)
    		{
    			while(head <= tail && q[head] < i-k) head++;//把过期的元素弹出
    			if(h[q[head]] <= h[i]) f[i] = f[q[head]] + 1;//先更新在把这个点入队
    			else f[i] = f[q[head]];
    			while(head <= tail && (f[q[tail]] > f[i] || (f[q[tail]] == f[i] && h[q[tail]] <= h[i]))) tail--;//特判一下f值相同的情况
    			q[++tail] = i;
    		}
    		printf("%d
    ",f[n]);
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    MSScriptControl .net 后台接收并计算前端输入的计算表达式
    IIS 应用程序池 配置:(asp.net+sqlserver)
    java 技术架构 for web
    java 学习汇总
    js获取数组对象再多数组中出现次数
    vue人脸识别
    快速压缩图片方法(小白篇)
    【其它】种草,长草,狂草,拔草等中英文翻译
    类Unix系统中,fd指的啥?
    带你了解以太网
  • 原文地址:https://www.cnblogs.com/genshy/p/13658630.html
Copyright © 2011-2022 走看看