Codeforces 1029B. Creating the Contest 动态规划O(nlogn)解法 及 单调队列O(n)解法
题目链接:http://codeforces.com/problemset/problem/1029/B
题目大意:从数组a中选出一些数组成数组b,要求 b[i+1]<=b[i]*2 。
一开始想到的是O(n^2)的动态规划,但是超时了,下面是超时的代码。
#include <iostream>
using namespace std;
const int maxn = 200020;
int n, a[maxn], f[maxn], res = 0;
int main() {
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
for (int i = 0; i < n; i ++) {
f[i] = 1;
for (int j = i-1; j >= 0 && a[i] <= 2*a[j]; j --) {
f[i] = max(f[i], f[j]+1);
}
if (f[i] > res) res = f[i];
}
cout << res << endl;
return 0;
}
然后想到的是:
- 二分找最小的满足a[i]<=a[j]*2的那个j ,O(logn)的时间复杂度
- 线段树求区间[j,i-1]的最大值,O(logn)的时间复杂度
再加上外层的循环,时间复杂度会降到O(n * logn)。
代码:
#include <iostream>
using namespace std;
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1
const int maxn = 200020;
int n, a[maxn], MAX[maxn<<2];
void pushUp(int rt) {
MAX[rt] = max(MAX[rt<<1] , MAX[rt<<1|1]);
}
void build(int l, int r, int rt) {
if (l == r) {
MAX[rt] = 0;
return;
}
int m = (l+r) >> 1;
build(lson);
build(rson);
pushUp(rt);
}
void update(int p, int val, int l, int r, int rt) {
if (l == r) {
MAX[rt] = val;
return;
}
int m = (l + r) >> 1;
if (p <= m) update(p, val, lson);
else update(p, val, rson);
pushUp(rt);
}
int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return MAX[rt];
}
int m = (l + r) >> 1;
int tmp = 0;
if (L <= m) tmp = query(L, R, lson);
if (R >= m+1) tmp = max(tmp, query(L, R, rson));
return tmp;
}
int findL(int i) {
return lower_bound(a, a+n+1, (a[i]+1)/2) - a;
}
int main() {
cin >> n;
build(1, n, 1);
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) {
int L = findL(i);
int val;
if (L >= i) val = 1;
else {
val = query(L, i-1, 1, n, 1) + 1;
}
update(i, val, 1, n, 1);
}
cout << query(1, n, 1, n, 1) << endl;
return 0;
}
然后是O(n)的单调队列解法。
代码:
#include <iostream>
using namespace std;
const int maxn = 200020;
int n, a[maxn], MAX[maxn];
int st = 0, ed = 0, sum = 0;
int que[maxn]; // que存放id,id对应的最大长度是MAX[id]
void test() {
cout << "[test]" << endl;
for (int i = 1; i <= n; i ++) {
cout << i << ": " << MAX[i] << endl;
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
int j = 1;
for (int i = 1; i <= n; i ++) {
while (j < i && !( a[i] <= 2 * a[j] )) {
j ++;
}
while (st < ed && que[st] < j) st ++;
if (st == ed) {
MAX[i] = 1;
} else {
MAX[i] = MAX[ que[st] ] + 1;
}
sum = max(sum , MAX[i]);
while (st < ed && MAX[ que[st] ] <= MAX[i]) {
st ++;
}
que[ed++] = i;
}
// test();
cout << sum << endl;
return 0;
}
Codeforces 1029B. Creating the Contest 动态规划O(nlogn)解法 及 单调队列O(n)解法的更多相关文章
- codeforce1029B B. Creating the Contest(简单dp,简单版单调栈)
B. Creating the Contest time limit per test 1 second memory limit per test 256 megabytes input stand ...
- Codeforces Round #189 (Div. 1) B. Psychos in a Line 单调队列
B. Psychos in a Line Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/p ...
- CodeForces B. Creating the Contest
http://codeforces.com/contest/1029/problem/B You are given a problemset consisting of nn problems. T ...
- 不失一般性和快捷性地判定决策单调(洛谷P1912 [NOI2009]诗人小G)(动态规划,决策单调性,单调队列)
洛谷题目传送门 闲话 看完洛谷larryzhong巨佬的题解,蒟蒻一脸懵逼 如果哪年NOI(放心我这样的蒟蒻是去不了的)又来个决策单调性优化DP,那蒟蒻是不是会看都看不出来直接爆\(0\)?! 还是要 ...
- 洛谷P3628 [APIO2010]特别行动队(动态规划,斜率优化,单调队列)
洛谷题目传送门 安利蒟蒻斜率优化总结 由于人是每次都是连续一段一段地选,所以考虑直接对\(x\)记前缀和,设现在的\(x_i=\)原来的\(\sum\limits_{j=1}^ix_i\). 设\(f ...
- 洛谷P3515 [POI2011]Lightning Conductor(动态规划,决策单调性,单调队列)
洛谷题目传送门 疯狂%%%几个月前就秒了此题的Tyher巨佬 借着这题总结一下决策单调性优化DP吧.蒟蒻觉得用数形结合的思想能够轻松地理解它. 首先,题目要我们求所有的\(p_i\),那么把式子变一下 ...
- Codeforces Round #189 (Div. 2) D. Psychos in a Line 单调队列dp
D. Psychos in a Line time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Codeforces Round #278 (Div. 1) B - Strip dp+st表+单调队列
B - Strip 思路:简单dp,用st表+单调队列维护一下. #include<bits/stdc++.h> #define LL long long #define fi first ...
- 动态规划专题(四)——单调队列优化DP
前言 单调队列优化\(DP\)应该还算是比较简单容易理解的吧,像它的升级版斜率优化\(DP\)就显得复杂了许多. 基本式子 单调队列优化\(DP\)的一般式子其实也非常简单: \[f_i=max_{j ...
随机推荐
- learning java AWT BoxLayout布局管理器
import javax.swing.*; import java.awt.*; public class BoxSpaceTest { private Frame f = new Frame(&qu ...
- 结构化异常SEH处理机制详细介绍(一)
结构化异常处理(SEH)是Windows操作系统提供的强大异常处理功能.而Visual C++中的__try{}/__finally{}和__try{}/__except{}结构本质上是对Window ...
- Linux中三种SCSI target的介绍之LIO
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/scaleqiao/article/deta ...
- Problem 2 线段树
$des$ 一个无限长的 01 序列,初始全为 0,每次选择一个区间 [l,r] 进行操作,有三种操作:1. l r 将 [l,r] 中所有元素变成 1.2. l r 将 [l,r] 中所有元素变成 ...
- javascript练习题
function Vertex(city, x) { this.name = city; this.num = x; } var node0 = new Vertex("邯郸", ...
- Kafka 幂等生产者和事务生产者特性(讨论基于 kafka-python | confluent-kafka 客户端)
Kafka 提供了一个消息交付可靠性保障以及精确处理一次语义的实现.通常来说消息队列都提供多种消息语义保证 最多一次 (at most once): 消息可能会丢失,但绝不会被重复发送. 至少一次 ( ...
- UOJ#121. 【NOI2013】向量内积 随机化算法,矩阵
原文链接www.cnblogs.com/zhouzhendong/UOJ121.html 前言 完蛋了我越来越菜了贺题都不会了. 题解 $O(n ^ 2 d) $ 暴力送 60 分. Bitset 优 ...
- 模板 - 数学 - 同余 - 扩展Euclid算法
普通的扩展欧几里得算法,通过了洛谷的扩展欧几里得算法找乘法逆元.修复了容易溢出的bug,虽然新版本仍有可能会溢出longlong,假如参与运算的数字都是longlong,假如可以的话直接使用__int ...
- Assignment3:白盒测试以及测试框架简介
一. 白盒测试简介 白盒测试又称结构测试.透明盒测试.逻辑驱动测试或基于代码的测试.白盒测试是一种测试用例设计方法,盒子指的是被测试的软件,白盒指的是盒子是可视的,你清楚盒子内部的东西以及 ...
- Ubuntu -- unknown error: Chrome failed to start: exited abnormally (Driver info: chromedriver=...)
#添加沙盒模式 chrome_options.add_argument("--no-sandbox")