[POJ]3017 单调队列 + set
来源:互联网 发布:我的世界方块数据值 编辑:程序博客网 时间:2024/06/06 10:08
Description
Given an integer sequence { an } of length N, you are to cut the sequence into several parts every one of which is a consecutive subsequence of the original sequence. Every part must satisfy that the sum of the integers in the part is not greater than a given integer M. You are to find a cutting that minimizes the sum of the maximum integer of each part.
Input
The first line of input contains two integer N (0 < N ≤ 100 000), M. The following line contains N integers describes the integer sequence. Every integer in the sequence is between 0 and 1 000 000 inclusively.
Output
Output one integer which is the minimum sum of the maximum integer of each part. If no such cuttings exist, output −1.
Sample Input
8 172 2 2 8 1 8 2 1
Sample Output
12
Hint
Use 64-bit integer type to hold M.
Source
[Submit] [Go Back] [Status] [Discuss]
Home Page Go Back To top
嗯...好题. 用到了单调性来优化复杂度.
首先dp方程很容易得到. f[i] = min(f[j] + max(f[j + 1] + f[j + 2]....f[i])). 因为所有值都为非负数, 所以f[1] <= f[2] <= f[3]. 所以对于i来说, 如果j, j + 1, j + 2 ... k到i的最大值是相同的话, 肯定取f[j - 1](最大值是从j开始算的)是最优的. 而且又因为从1, 2, 3, ... i-1, i 到i的最大值肯定是单调不上升的, 那么用一个单调递减的维护最大值的位置, 然后当前 最大值+单调队列里上一个最大值的点的f(从上一个的之后最大值就是当前的, 所以相同最大值肯定要维护最后出现的, 所以单调递减, 而非不上升). 插入multiset里面求最小值即可(单调队列队首只是最大最大值,不代表是最优解) . 注意特判有点多.
#include<stdio.h>#include<set>#ifdef WIN32#define aut "%I64d"#else#define aut "%lld"#endifusing namespace std;multiset<int> s;const int maxn = 100005;typedef long long dnt;bool flag;int n, a[maxn], q[maxn];dnt temp, f[maxn], m, sum;int main(){scanf("%d"aut, &n, &m);flag = true;for(int i = 1; i <= n; ++i){scanf("%d", &a[i]);if(a[i] > m) flag = false;}if(!flag) {puts("-1"); return 0;}int low = 1, h = 1, t = 0;for(int i = 1; i <= n; ++i){sum += a[i];while(sum > m) sum -= a[low], ++low; while(h <= t && a[q[t]] <= a[i]){if(t > h) s.erase(f[q[t - 1]] + a[q[t]]);--t;}q[++t] = i;if(t > h) s.insert(f[q[t - 1]] + a[q[t]]);while(low > q[h]){if(t > h) s.erase(f[q[h]] + a[q[h + 1]]);++h;}temp = *(s.begin()), f[i] = f[low - 1] + a[q[h]];if(h < t && temp < f[i]) f[i] = temp; }printf(aut, f[n]);}
- [POJ]3017 单调队列 + set
- poj 3017 Cut the Sequence dp 单调队列+set
- poj 3017 Cut the Sequence(DP+单调队列+set)
- POJ 3017 单调队列dp
- poj 3017 dp+单调队列优化
- poj 3017 单调队列+dp+sbt
- POJ 3017 单调队列优化DP
- poj 3017 单调队列优化DP
- POJ 3017 Cut the Sequence 单调队列
- Poj 2823 (单调队列)
- poj 2823【单调队列】
- POJ 2823 单调队列
- POJ-2823单调队列
- POJ 2823 单调队列
- poj 2823 单调队列
- 单调队列 POJ 2823
- poj 2823 单调队列
- POJ 2823 单调队列
- 网页实现 在线咨询(联系客服)
- Echart常见使用问题总结(个人笔记)
- 封装getByClass(JS获取class的方法封装为一个函数)
- Gradle系列第(三)篇---Android Studio与Gradle那些事儿
- 【安全牛学习笔记】中间人攻击、ARP MITM、中间人攻击、Pass the Hash
- [POJ]3017 单调队列 + set
- txt文件导入mysql
- java正则实现身份证号码匹配
- .XML之三 简单xml文档对象模型
- Android JNI编程入门
- 文件系统损坏导致虚拟机无法正常启动的问题及解决方法
- Hadoop YARN配置参数剖析(4)—Fair Scheduler相关参数
- Solr中使用游标进行深度分页查询以提高效率(适用的场景下)
- java中如何连接mysql数据库