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;
    }
    
  • 相关阅读:
    汉字乱码、加密后结果字符串不一致
    msgpack和TParams互相转换
    unigui监听会话开始和结束
    System.JSON.Builders.pas
    保证最终一致性的模式
    使用 Delta Sharing 协议进行数据共享
    dremio 16 升级问题
    graylog 4.0 运行
    supabase 开源firebase 可选工具
    cube.js 最新playground 说明
  • 原文地址:https://www.cnblogs.com/Potassium/p/9903755.html
Copyright © 2011-2022 走看看