zoukankan      html  css  js  c++  java
  • P1725 琪露诺 题解(单调队列)

    题目链接

    琪露诺

    解题思路

    单调队列优化的(dp)
    状态转移方程:(f[i]=max{f[i-l],f[i-l+1],...,f[i-r-1],f[i-r]}+a[i])
    考虑单调队列优化。
    因为刚学,不是很熟悉单调队列,特写一篇详细的解释。
    (queue) 数组存储一个队列,他的头部和尾部的下标分别用head和tail表示。
    (f) 数组是(dp)用到的数组。
    首先读入每一个坐标处的价值(a[i])
    枚举(i),从(l)(n),分别计算(f[i]),当(i+r>n)时,存储最大值ans。
    单调队列的注释写在代码中。

    AC代码

    #include<stdio.h>
    int i,n,l,r,a[200010],f[200010],ans=-2147483648;//这个题数据比较水,ans=0也能过,但理论上是不允许这样的
    int queue[200010],head=0,tail=-1;
    int main(){
    	scanf("%d%d%d",&n,&l,&r);
    	for(i=0;i<n;i++){
    		scanf("%d",&a[i]);
    	}
    	for(i=l;i<=n;i++){
    		while(head<=tail&&queue[head]+r<=i)head++;//如果头太靠前了,那就删掉
    		while(head<=tail&&f[queue[tail]]<=f[i-l])tail--;//如果尾巴对应的a太小了,那就删掉
             //这两句保证了单调队列的不上升也即单调减特性,保证头永远是当前状态的最佳状态
    		queue[++tail]=i-l;//存储上一次是从哪里来的
    		f[i]=a[i]+f[queue[head]];//从上一步跳过来,跳到这里的最大值
    		if(i>n-r&&f[i]>ans)ans=f[i];
    	}
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    多变的鸭子策略模式
    反序列化和序列化
    UBUNTU eclipse必须是 jdk5.0以上
    Ubuntu Linux:MySQL安装指南
    phpMyAdmin下载、安装和使用入门
    读者-写者问题
    wget用法2
    在linux下安装mysql
    linux下数字转成字符串
    [SQLServer]必须知道的SQL
  • 原文地址:https://www.cnblogs.com/Potassium/p/9903755.html
Copyright © 2011-2022 走看看