HDU 5489 Removed Interval (dp+线段树) 2015合肥网络赛
来源:互联网 发布:java socket 长链接 编辑:程序博客网 时间:2024/05/16 12:39
题意:
给定一个长度为
N<=105 的序列 求删去长度为0<=L<=N 的序列后的LIS
分析:
假设你已经会
O(nlogn)的LIS ,删去i 前面连续一段长度为L 即[i−L,i−1] 的序列, 左边是i−L−1 , 右边是i , 求剩下的LIS
首先预处理出:
f[i]:=以a[i]结尾的LIS的最大长度
g[i]:=以a[i]开头的LIS的最大长度
我们可以根据i , 找到[0,i−L−1] 之间的一个值
其值小于a[i] , 而其f[i] 值是最大的, 也就是O(n2) 求LIS的思想
关键是如何快速确定在[0,i−L−1] 中, 找到这个值
我们利用线段树和离散化, 将a[i] 映射到线段树上
假设i 位置对应的值是x ,并且其映射到线段树上对应的下标是y
那么我们只要在线段树上查找[0,y−1] 之间的最大值maxv
maxv[i]=max{f[j],j∈[0,i−L+1]∪a[j]<a[i]}
其实就是dp[i]:= 以a[i] 结尾, 删去[i−L,i−1] 长度为L 的LIS 的最大长度
dp[i]=maxv[i]+g[i],ans=max{dp[i]}
代码:
//// Created by TaoSama on 2015-09-27// Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << " "#define prln(x) cout << #x << " = " << x << endlconst int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;int n, L, a[N], all[N];int f[N], g[N], h[N];int maxv[N << 2];void update(int o, int v, int l, int r, int rt) { if(l == r) { maxv[rt] = max(maxv[rt], v); return; } int m = l + r >> 1; if(o <= m) update(o, v, l, m, rt << 1); else update(o, v, m + 1, r, rt << 1 | 1); maxv[rt] = max(maxv[rt << 1], maxv[rt << 1 | 1]);}int query(int L, int R, int l, int r, int rt) { if(L <= l && r <= R) return maxv[rt]; int m = l + r >> 1, ret = -INF; if(L <= m) ret = max(ret, query(L, R, l, m, rt << 1)); if(R > m) ret = max(ret, query(L, R, m + 1, r, rt << 1 | 1)); return ret;}int main() {#ifdef LOCAL freopen("in.txt", "r", stdin);// freopen("out.txt","w",stdout);#endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); int kase = 0; while(t--) { scanf("%d%d", &n, &L); for(int i = 1; i <= n; ++i) { scanf("%d", a + i); all[i] = a[i]; } sort(all + 1, all + 1 + n); int m = unique(all + 1, all + 1 + n) - all - 1; memset(h, 0x3f, sizeof h); for(int i = 1; i <= n; ++i) { int k = lower_bound(h + 1, h + 1 + n, a[i]) - h; f[i] = k; h[k] = a[i]; } memset(h, 0x3f, sizeof h); for(int i = n; i; --i) { int k = lower_bound(h + 1, h + 1 + n, -a[i]) - h; g[i] = k; h[k] = -a[i]; } int ans = 0; a[n + 1] = INF; g[n + 1] = 0; memset(maxv, 0, sizeof maxv); //delete [i-l,i-1] length:l [0,i-l-1]->maxv for(int i = L + 1; i <= n + 1; ++i) { int o = lower_bound(all + 1, all + 1 + m, a[i]) - all; ans = max(ans, query(0, o - 1, 0, m, 1) + g[i]); o = lower_bound(all + 1, all + 1 + m, a[i - L]) - all; //插入一个新的 if(i <= n) update(o, f[i - L], 0, m, 1); } printf("Case #%d: %d\n", ++kase, ans); } return 0;}
0 0
- HDU 5489 Removed Interval (dp+线段树) 2015合肥网络赛
- 2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)
- hdu 5489 Removed Interval 2015合肥网络赛 树状数组 dp 离散化/dp
- HDU 5489 Removed Interval (合肥网络赛 1006 )
- HDU 5489 Removed Interval(2015合肥站网赛1006,DP+树状数组)
- hdu5489 Removed Interval(dp+线段树)
- Hdu 5489 Removed Interval【LIS+线段树】
- hdu 5489 Removed Interval(线段树+LIS)
- HDU 5489 Removed Interval(DP)
- HDU 5493 Queue (线段树) 2015合肥网络赛
- hdu 5493 线段树(2015年合肥网络赛)
- hdu 5489 Removed Interval
- HDU 5493 Queue (线段树)2015合肥赛区网络赛
- HDU 5489 Removed Interval (LIS,变形)
- [HDU 5489]Removed Interval[LIS]
- hdu-5489(2015网络赛合肥赛区)***
- HDU 5492 Find a path (dp) 2015合肥网络赛
- 【HDU】5489 Removed Interval(2015 ACM/ICPC Asia Regional Hefei Online)
- HT for Web 中Painter的介绍及用法
- *LeetCode-Search a 2D Matrix II
- 成为更优秀开发者的10条途径
- tps65910
- vector容器易错知识点集锦
- HDU 5489 Removed Interval (dp+线段树) 2015合肥网络赛
- iOS开发小白学习体验-UICollectionView(一)
- Java运行cmd命令并显示输出信息
- Ember.js 入门指南——loading、error子状态
- #6 LeetCode——ZigZag Conversion
- iOS开发小白学习体验-11
- iOS开发小白学习体验-CALayer的一些整理
- Swing__JComboBox 用法
- 闭包深入理解