码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3214 Heap 动态规划法题解

时间:2014-12-05 12:45:02      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   io   ar   color   os   使用   

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. Upon this we further require that for every node that has two children, key of any node in the subtree rooted at its left child should be less than that of any node in the subtree rooted at its right child.

Any array can be transformed into a max-heap satisfying the above requirement by modifying some of its keys. Your task is find the minimum number of keys that have to be modified.

Input

The input contains a single test case. The test case consists of nonnegative integers distributed on multiple lines. The first integer is the height of the heap. It will be at least 1 and at most 20. Then follow the elements of the array to be transformed into a heap described above, which do not exceed 109. Modified elements should remain integral though not necessarily nonnegative.

Output

Output only the minimum number of elements (or keys) that have to be modified.

Sample Input

3
1
3 6
1 4 3 8

Sample Output

4

Hint

   1                 10
  / \               /   3   6    =====>   3    9
/ \ / \           / \  / 1 4 3 8           1 2  4 8

Source


本题虽然知道是动态规划法,但是建模真的好难。

这里是要把二叉树转换成为数组,然后求最长非递减子序列的。

还需要注意处理其中的大于和大于等于的区别,这样建模的难度真的很高呢。

#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 = 1 << 20 | 1;
int tree[MAX_N], AN;//AN是arr的元素个数, tree下标从1开始
int arr[MAX_N], id;//arr下标从0开始
inline int lSon(int rt) { return rt << 1; }
inline int rSon(int rt) { return rt << 1 | 1; }

void postOrderToArr(int rt, int &span)//因为l<r,故此需要确保条件成立,就可以改成l <= r-1,使用span来确保所有的子树都l<=r-1
{
	if (lSon(rt) <= AN) postOrderToArr(lSon(rt), span);
	if (rSon(rt) <= AN) postOrderToArr(rSon(rt), ++span);
	arr[id++] = tree[rt] - span;
}

int biGetIndex(int low, int up, int val)
{
	while (low <= up)
	{
		int m = low + ((up-low)>>1);
		if (arr[m] > val) up = m-1;
		else low = m+1;
	}
	return low;
}

int getLIS()
{
	int cur = 0;
	for (int i = 1; i < AN; i++)
	{
		if (arr[i] >= arr[cur]) arr[++cur] = arr[i];//这里只是小小的优化,其实可以不用if else判断
		else
		{
			arr[biGetIndex(0, cur, arr[i])] = arr[i];
		}
	}
	return cur+1;
}

int main()
{
	int N;
	AN = 0;//arr 下标从1开始
	scanf("%d", &N);
	int a;
	while (~scanf("%d", &a))
	{
		tree[++AN] = a;
	}
	/*这样计算有误???
	for (int i = 0; i < N; i++)
	{
		int j = 1 << i;
		for (int k = 0; k < j; k++)
		{
			scanf("%d", tree + (++AN));
		}
	}*/
	id = 0;
	int span = 0;
	postOrderToArr(1, span);
	printf("%d\n", AN-getLIS());
	return 0;
}




POJ 3214 Heap 动态规划法题解

标签:des   style   blog   http   io   ar   color   os   使用   

原文地址:http://blog.csdn.net/kenden23/article/details/41745727

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!