书架_纪中2931_dp_堆_单调队列
来源:互联网 发布:淘宝客好做不 编辑:程序博客网 时间:2024/06/07 19:20
题目大意
当Farmer John闲下来的时候,他喜欢坐下来读一本好书。 多年来,他已经收集了N本书 (1 <= N <= 100,000)。 他想要建立一个多层书架,来存放它们。 每本书 i 拥有一个宽度 W(i)和一个高度 H(i)。 所有的书需要按顺序,放到书架的每一层。 举例来说,第一层书架放k本书,应该放书1...k;第二层书架从第k+1本书开始放……。 每层书架的宽度最多为L (1 <= L <= 1,000,000,000)。 每层书架的高度为该层最高的那本书的高度。 书架的总高度为每层书架高度之和。 请帮FJ计算书架可能的最小总高度。
分析
一眼就看出是 dp (因为每天的第四或第三题都是dp)
最简单的方程是
f[i]=min{f[j]+max(h[j],h[j+1]...h[i])}
其中w[j]+w[j+1]...w[i]<=l。
但是这个东西是O(n²),会超时。所以联系到求最大值,可以想到用最大值的单调队列,队列里面存放的是以 i 为结尾,窗口里面的元素和恰好不大于 M 的 j 为左边界,即恰好有 sum[i] - sum[j-1] <= M.同时h也用单调队列优化。
然后这样一个可行解就是,f[ i ]=f[j]+h[a[r]](即队首元素的值), 这并不是最优解,所以还要找到队列中的最优解,一个可能的最优解只能是这样的f[i]=f[a[r-1]]+h[a[r]],也就是 a[ r ] 要大于后面的数,很显然,如果a[ r]小于后面的数,那么我们就可以将 a[ r ] 划分到后面去,而取得更优解。这里涉及的这个找最优解问题,可以用set。
看不懂的自行脑补(虽然我也不是很知道我在打什么,具体的见代码)
又是他—— 蜜汁c++
代码
#include <stdio.h> #include <iostream>#include <sstream> #include <set>using namespace std; typedef long long ll; ll que[100100],a[100100],dp[100100],b[100100]; ll n,m,sum;ll i,j,k;ll front,rear,p=1;multiset <ll> lxf; //erase insert begin int main() { scanf("%lld%lld",&n,&m); for(i=1;i<=n;i++){ scanf("%lld%lld",&a[i],&b[i]); } front=1; rear=1; dp[1]=a[1];que[rear]=1; sum=b[1]; for(i=2;i<=n;i++){ sum+=b[i]; while(sum>m) sum-=b[p++]; while( front<=rear&&a[i]>=a[que[rear]]){ lxf.erase(dp[que[rear-1]]+a[que[rear]]); rear--; } rear=rear+1; que[rear]=i; if (front<rear) { lxf.insert(dp[que[rear-1]]+a[que[rear]]); } while(que[front]<p&&front<=rear){ lxf.erase(dp[que[front]]+a[que[front+1]]); front++; } dp[i]=dp[p-1]+a[que[front]]; j=*lxf.begin(); if ((j<dp[i])&&(j!=0)) dp[i]=j; } cout<<dp[n]<<endl; return 0; }
- 书架_纪中2931_dp_堆_单调队列
- 书架_纪中2931_dp+堆+单调队列优化
- Window_纪中1326_水_单调队列
- 优先队列_二叉堆
- shu_1078 vijos_1091(环城旅行)_单调队列
- 奶牛晒衣服_纪中1744_贪心+堆
- 堆排序_最大优先队列
- 滑动窗口_单调队列入门 (白书P241)
- BZOJ 1514 _ [POI2006]ZAB-Frogs 单调队列+二分BFS
- 动态规划中的单调队列优化_补充
- 浅谈数据结构_堆[更新中]
- 数据结构_使用二叉堆实现优先队列
- <斜率优化><单调队列>——2.T_OY(踢欧阳^_^)
- POJ 3162 Walking Race 树的直径+单调队列(其实暴力也可以>_<)
- Window_纪中_1326_单调队列
- 删除_纪中1381_暴力
- 输油管道_纪中1432_暴力
- 直角三角形_纪中2543_暴力?
- js封装表单通用函数
- DataBase数据库学习
- 统计及其学习概念解析001
- LightOJ - 1067 Combinations(快速幂+逆元)
- 快速排序
- 书架_纪中2931_dp_堆_单调队列
- SAE Python 后台1
- 【MyBatis框架】高级映射-一对多查询
- cscope.exe程序的base64文本
- JAVA代理模式--静态代理
- seajs 3.0.0 源码阅读笔记
- 一个关于EPOLLET和EPOLLLT的问题
- Linux守护进程加上发送信号固定模式
- iOS Autolayout 介绍 2 Interface Builder 技巧