Heap 3214 LIS题解

根据问题转换成最长不降子序列问题。

10^9的输入数据计算起来还是挺花时间的。因为这里只能使用O(nlgn)时间复杂度了。不过证明是可以算出10^9个数据的。因为时间限制是5s.

#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <limits.h>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;

const int MAX_N = 20;
vector<int> arr, a2;
int N;

inline int lSon(int rt) { return rt<<1|1; }
inline int rSon(int rt) { return (rt<<1)+2; }

void postOrder(int rt, int &v)
{
	int l = lSon(rt), r = rSon(rt);
	if (l < N) postOrder(l, v);
	if (r < N) postOrder(r, ++v);
	a2.push_back(arr[rt]-v);
}

int biGetIndex(int low, int up, int v)
{
	while (low <= up)
	{
		int mid = low + ((up-low)>>1);
		if (v < a2[mid]) up = mid-1;
		else low = mid+1;
	}
	return low;
}

int LIS()
{
	int j = 0;
	for (int i = 1; i < N; i++)
	{
		if (a2[i] >= a2[j]) a2[++j] = a2[i];
		else
		{
			int id = biGetIndex(0, j, a2[i]);
			a2[id] = a2[i];
		}
	}
	return j+1;
}

int main()
{
	int a;
	scanf("%d", &N);
	arr.clear(), a2.clear();
	while (scanf("%d", &a) != EOF)
	{
		arr.push_back(a);
	}

	N = (int) arr.size();
	int v = 0;
	postOrder(0, v);
	int len = LIS();
	printf("%d\n", N-len);
	return 0;
}
时间: 2024-10-28 19:32:15

Heap 3214 LIS题解的相关文章

HDU 1025 Constructing Roads In JGShining&#39;s Kingdom LIS题解

本题是LIS题解.主要是理解他的题意.他的题意都好像比较隐晦,比如每个poor city和rich city一定是需要对应起来的,比如poor city和rich city并不是按顺序给出的. 其实是可以把数列按照poor city排序,然后求rich city城市号的最大递增子序列. 不过这里不用排序,利用hash的思想直接对应起来就可以了. 然后就是本题是卡DP的O(n*n)的解法的,这里需要O(nlgn)的LIS解法. 二分好已经找到的递增序列,插入新的数值就可以了.是利用了一个单调队列的

HDU5489 LIS变形

Removed Interval Problem Description Given a sequence of numbers A=a1,a2,…,aN , a subsequence b1,b2,…,bk of A is referred as increasing if b1<b2<…<bk . LY has just learned how to find the longest increasing subsequence (LIS).Now that he has to se

POJ 3214 Heap 动态规划法题解

Description A (binary) heap is an array that can be viewed as a nearly complete binary tree. In this problem, we are talking about max-heaps. A max-heap holds the property that for each node than the root, it's key is no greater than its parent's. Up

【CF486E】LIS of Sequence题解

[CF486E]LIS of Sequence题解 题目链接 题意: 给你一个长度为n的序列a1,a2,...,an,你需要把这n个元素分成三类:1,2,3: 1:所有的最长上升子序列都不包含这个元素 2:有但非所有的最长上升子序列包含这个元素 3:所有的最长上升子序列都包含这个元素 输入格式: 第一行包含一个正整数n,表示序列的长度.第二行包含n个正整数a1,a2,...,an,表示序列中的元素. 输出格式: 一行,包含一个长度为n的.由1,2,3三种数字组成的字符串,第i个数字表示ai所属类

PAT甲题题解1098. Insertion or Heap Sort (25)-(插入排序和堆排序)

题目就是给两个序列,第一个是排序前的,第二个是排序中的,判断它是采用插入排序还是堆排序,并且输出下一次操作后的序列. 插入排序的特点就是,前面是从小到大排列的,后面就与原序列相同. 堆排序的特点就是,后面是从小到大排列的最大的几个数p~n-1,前面第一位则是p-1. 所以只要先按照插入排序的特点来判断是否为插入排序,接下来再进行操作就可以了,这里要手动写下最大堆的更新操作. 代码: #include <iostream> #include <cstdio> #include <

Codeforces 486E LIS of Sequence 题解

题目大意: 一个序列,问其中每一个元素是否为所有最长上升子序列中的元素或是几个但不是所有最长上升子序列中的元素或一个最长上升子序列都不是. 思路: 求以每一个元素为开头和结尾的最长上升子序列长度,若两者相加比最长上升子序列长度+1小,则一个也不是:否则若有另一元素与它的两个值完全相同,则不是所有;否则在所有. 代码: 1 #include<map> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace st

QAQ的LIS树 QAQ的LIS树2 题解报告

这两道题实际上考试的时候是一道题OwO 太可怕了,忙了我三个多小时,写了整整7K 这个题两个询问关联性不强,所以分开来考虑 QAQ的LIS树 考虑如何用dp求解答案 设dp(v)表示v到根的修改后的序列的和,c(v)是v点点权 那么v的答案就是dp(v)减去v到根的点权和 最直观的想法是我们从v点向上暴力跳父亲,跳到第一个不用修改的点u 不难发现因为u没有修改,所以之后的序列和u之后的序列是完全一样的 可以直接转移给v了,那么dp(v)的值就是dp(u)和v->u的序列和了 注意到v->u的所

题解报告:poj 2533 Longest Ordered Subsequence(LIS)

Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence ( a1, a2, ..., aN) be any sequence ( ai1, ai2, ..., aiK), where 1 <= i1 < i2 < ... < iK <= N. For example, seq

ZOJ 3963 Heap Partition(multiset + stl自带二分 + 贪心)题解

题意:给你n个数字s1~sn,要你把它们组成一棵棵二叉树,对这棵二叉树来说,所有节点来自S,并且父节点si<=子节点sj,并且i<j,问你树最少几棵二叉数.树 思路:贪心.我们往multiset加还能加子节点的节点,二分查找一个个大于等于当前插入节点的节点,然后插入,若找不到则重新建一棵树. 没想到set自带lower_bound(),第一次迭代器遍历TLE就想着手动写二分...然后发现自带二分... 代码: #include<iostream> #include<stdio