474E Pillars

线段树dp,有一个数组,从i->j必须满足 abs(a[i]-a[j])>=h。求这样可以最多跳多少步。首先想到的是最简单的 n^2dp,不多说。显然需要优化下,在这里就用到线段树了,如果当前位置在a[i],那么只要查询大于等于a[i]+h中最大的高度,和 小于等于a[i]-h的最大高度,就可以了,然后更新下高度为a[i]时候可以到达的最大步数。需要离散化处理下,unique lower_bound upper_bound需要很熟练。下面的代码只是求了最大的步数,没有输出路径。

 

线段树好久没写,也要注意下,idx>=1,l和r表示是所有的范围,都是取闭区间。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <cassert>
#include <stack>
#include <map>
using namespace std;

typedef long long ll;


int segtree[410000];
//idx >=1
void update(int idx, int pos, int val,int l, int r){
	//cout << idx << endl;
	if (l == pos && r == pos) {
		segtree[idx] = max(segtree[idx], val);
		return;
	}
	int mid = (l + r) /2;
	if (mid < pos) update(idx * 2 + 1, pos, val, mid+1, r);
	else update(idx * 2, pos, val, l, mid);
	segtree[idx] = max(segtree[idx * 2], segtree[idx * 2 + 1]);

}
//[x,y] 找最大
int getMax(int idx, int x,int y,int l,int r){
	if (x <= l&&y >= r) return segtree[idx];
	if (y<l || x>r) return 0;
	int mid = (l + r) / 2;
	return max(getMax(idx * 2, x, y, l, mid), getMax(idx * 2+1, x, y, mid + 1, r));
}

int dp[110000];
int main(){
	int n, h;
	while (cin >> n >> h){
		vector<int>height(n);
		for (int i = 0; i < n; i++)
			cin >> height[i];
		map<int, int>posma;
		vector<int>tmp_cpy,unique_height;
		tmp_cpy = height;
		sort(height.begin(), height.end());
		height.erase(unique(height.begin(), height.end()),height.end());

		for (int i = 0; i < tmp_cpy.size(); i++){
			int idx = lower_bound(height.begin(), height.end(), tmp_cpy[i]+h) - height.begin();
			//cout <<"big:" <<idx << endl;
			int ans = 0;
			if (idx < height.size()){
				ans = getMax(1, idx+1, height.size(), 1, height.size());
			}
			idx = upper_bound(height.begin(), height.end(), tmp_cpy[i] - h) - height.begin();
			//cout <<"small "<< idx << endl;
			if (idx < height.size()&&idx>0)
				ans = max(ans, getMax(1, 1, idx, 1, height.size()));
			idx = lower_bound(height.begin(), height.end(), tmp_cpy[i]) - height.begin();

			//ma[idx + 1] = i;
			update(1, idx+1, ans + 1, 1, height.size());
		}
		cout << getMax(1, 1, height.size(), 1, height.size());
	}
}

你可能感兴趣的:(474E Pillars)