zoukankan      html  css  js  c++  java
  • [笔记][题解]单调队列优化DP&lgP1725琪露诺

    原题链

    初始思路

    这道题一看就是(dp)题,设(f[x])是到(x)位置的最大冰冻效果,转移的话就是:(f[x]=max(f[k])+val[x] -- k∈[x-r,x-l]),但是由于数据范围的原因,裸的(dp)是不行的,我们发现我们求的是最大值,而且有转移方程是得知是一个最值加上一个定值,所以我们考虑维护这个最值,那么就自然地想到单调队列.

    进阶思路

    我们用单调队列维护最大值,就要保证队列的元素是单调递减的,在转移的时候也不用去找(k∈[x-r,x-l])这个范围,直接去队列的队首元素即可.

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n,l,r,a[2000010],f[2000010];
    int ans=-INT_MAX;
    deque < int > q;
    int main(){
    	scanf("%d%d%d",&n,&l,&r);
    	for(int i = 1;i <= 2 * n;i++)f[i] = -INT_MAX;
    	for(int i = 0;i <= n;i++) scanf("%d",&a[i]);
    	for(int i = 0;i <= n;i++){
    		while(!q.empty() && f[i] > f[q.back()]) q.pop_back();
    		q.push_back(i);
    		while(!q.empty() && q.front() < i - r + l) 
    			q.pop_front();//超过了可以跳跃的范围,就直接弹出
    		f[i + l] = f[q.front()] + a[i + l];//单调队列维护的最大值在队头
    	}
    	for(int i = n + 1;i <= n + l;i++)//因为最终会跳出去,所以去外面找,初始化的时候也要注意多初始化一倍
    		ans = max(ans,f[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    AutoMapper 使用实践
    项目重构之路
    Xamarin对Visual Studio用户免费 Xamarin SDK将开源
    php的文件上传及下载,附带显示文件及目录
    SMARTY静态缓存
    SMARTY的简单实例写法
    SMARTY的知识
    wampserver的使用配置
    php权限管理
    phpcms企业站的一些知识
  • 原文地址:https://www.cnblogs.com/czy--blog/p/13862712.html
Copyright © 2011-2022 走看看