问题
大房间里飘着N个气球。气球从左到右排成一列。珍苏喜欢用箭训练打猎。珍苏从左到右射箭。
高度是随意选择的。箭是在选择的高度H上,往面向气球的方向从左到右移动。箭面向气球的瞬间,气球会爆炸,然后消失。然后箭继续往右移动时,高度会降低1。所以在高度H上移动的箭,打破气球后,高度会成为H-1。
我们的目标是打破所有气球时,尽量使用最少的箭。
输入
第一行,会给出整数N(1 ≤ N ≤ 1 000 000)。
第二行,会给出N个 Hi排列。
每个Hi(1 ≤ Hi ≤ 1 000 000)是第i个气球的高度,是从左到右罗列的顺序。
输出
第一个行上输出最少需要的箭数量。
案例输入 1
5
2 1 5 4 3
案例输出1
2
案例输入2
5
1 2 3 4 5
案例输出2
5
案例输入3
5
4 5 2 1 4
案例输出3
3
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std;
const int MAXN = 1 << 20;
int n;
set <int> S[MAXN];
int find (int pos, int v) {
set<int>::iterator it = S[v].lower_bound(pos);
if(it == S[v].end()) return -1;
return *it;
}
int v[MAXN];
int main (void){
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d", &v[i]);
S[v[i]].insert(i);
}
intans = 0;
for(int i = 0; i < n; ++i) {
if(S[v[i]].count(i) == 0) continue;
int pos = i;
++ans;
while (pos >= 0) {
S[v[pos]].erase(pos);
pos = find(pos, v[pos] - 1);
}
}
printf("%d\n", ans);
return 0;
}