CS53 C 单调栈
给出一个目标序列,初始序列为0,你有一种操作方式可以将某段值相同的区间全部加上一定的值,问得到目标序列的最小次数。
开始没注意要求值相同,想都不想就暴力了,后来发现对于每个峰,只要找每个相对峰顶的阶数相同的数中数字相同的个数,最后总数减掉相同的就行了。
说的这么复杂,后来才发现换成图形就是找最小覆盖矩形的个数,于是用单调栈维护就行了。
顺便%rk1的yoseisan,1个小时就AK了orz 还有50刀的first prize...
/** @Date : 2017-10-18 23:43:41 * @FileName: C.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair<int ,int> #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; int a[N]; int main() { int n; cin >> n; for(int i = 1; i <= n; i++) scanf("%d", a + i); stack<int>s; int cnt = 0; for(int i = 1; i <= n; i++) { while(!s.empty() && a[s.top()] > a[i]) s.pop(); if(s.empty() || !s.empty() && a[s.top()] != a[i]) cnt++; s.push(i); } cout << cnt << endl; return 0; }