• 【洛谷P4954】Tower of Hay 干草塔【单调队列dp】


    题目大意:

    题目链接:https://www.luogu.org/problem/P4954
    为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉。干草包会从传送带上运来,共会出现N包干草,第i包干草的宽度是W i ,高度和长度统一为1。干草塔要从底层开始铺建。贝西会选择最先送来的若干包干草,堆在地上作为第一层,然后再把紧接着送来的几包干草包放在第二层, 再铺建第三层……重复这个过程, 一直到所有的干 草全部用完。每层的干草包必须紧靠在一起,不出现缝隙,而且为了建筑稳定,上层干草的宽度不能超过下层的宽度。 按顺序运来的干草包一定要都用上, 不能将其中几个干草包弃置不用。贝西的目标是建一座最高的塔,请你来帮助她完成这个任务吧。


    思路:

    把原数列反过来,其实就是要求每次选择的区间必须大于上次选择的区间和。
    但是贪心选取是错误的。例如洛谷题解中的这个例子:

    9 8 2 1 5 59 8 2 1 5 5
    贪心选法:551 2 8 95|5|1 2 8 9
    正确选法:55 1 2895|5 1 2|8|9

    那么可以考虑用dpdp解决。
    f[i]f[i]表示前ii个干草堆可以堆成的最大高度,len[i]len[i]表示在堆成最大高度的前提下,最上面一层的最小宽度,sumsum是干草堆宽度的前缀和。
    那么有方程
    f[i]=max(f[j])+1     sum[i]sum[j]len[j]f[i]=max(f[j])+1 | sum[i]-sum[j]geq len[j]
    由于ff肯定是单调不减的,所以上述方程的jj尽量大会更优。
    如何取到满足sum[i]sum[j]len[j]sum[i]-sum[j]geq len[j]的尽量大的jj呢?
    变形一下成为sum[i]sum[j]+len[j]sum[i]geq sum[j]+len[j]
    所以我们可以维护一个单调队列存sum[j]+len[j]sum[j]+len[j],在转移的时候不断弹出前面的满足sum[i]sum[j]+len[j]sum[i]geq sum[j]+len[j]的元素,只保留最后一个满足sum[i]sum[j]+len[j]sum[i]geq sum[j]+len[j]的元素进行转移。因为这个元素前面的转移显然没有在这个元素开始转移更优,而后面的就不满足转移的前提。
    时间复杂度O(n)O(n)


    代码:

    #include <queue>
    #include <cstdio>
    using namespace std;
    
    const int N=100010;
    int n,last,a[N],f[N],sum[N],len[N];
    deque<int> q;
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=n;i>=1;i--)
    		scanf("%d",&a[i]);
    	for (int i=1;i<=n;i++)
    		sum[i]=sum[i-1]+a[i];
    	q.push_back(0);
    	for (int i=1;i<=n;i++)
    	{
    		last=-1;
    		while (q.size() && len[q.front()]+sum[q.front()]<=sum[i])
    			last=q.front(),q.pop_front();
    		if (last!=-1) q.push_front(last);  //只保留一个满足转移条件的元素来转移
    		f[i]=f[q.front()]+1;
    		len[i]=sum[i]-sum[q.front()];
    		while (q.size() && len[i]+sum[i]<len[q.back()]+sum[q.back()])
    			q.pop_back();  //维护单调性
    		q.push_back(i);
    	}
    	printf("%d",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    go 自定义RWMutex
    go defer的*i和i参数
    go defer 易错题
    EasyPlayer移动端播放webrtc协议时长按播放页面无法关闭“关于我们”页面
    高速公路服务区智能一体机解决方案
    【操作教程】TSINGSEE青犀视频平台如何将旧数据库导入到新数据库?
    EasyPlayer流媒体播放器播放HLS视频,起播速度慢的技术优化
    开发那些事儿:如何在CentOS7下安装部署ffmpeg?
    开发那些事儿:前端开发环境报错“[vuex]unknown action type”如何解决?
    H.264转码H.265出现崩溃并报错“missing picture”该如何解决?
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998017.html
Copyright © 2020-2023  润新知