题目地址
题目思路:
对一个区间,只考虑2操作结果为(r - l + 1),加入1操作时,一定执行 t = min(al,al+1,al+2…,ar)次才能使结果最优化,对剩余区间不断执行以上操作,直至结果最优化。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define debug(x) cout<<#x<<" is "<<x<<endl
#define pb push_back
//#define dbg
const int N = 5000 + 5;
int a[N],n, l = -1,r;
vector<pair<int,int> > v;
ll ans = 0;
ll solve(int l,int r){
if(l > r || l < 1 || r > n)return 0LL;
if(l == r)return 1LL;
int minn = INT_MAX;
vector<int> zeros;
for(int i = l;i <= r;i++){
minn = min(a[i],minn);
}
for(int i = l;i <= r;i++){
a[i] -= minn;
if(a[i] == 0)
zeros.pb(i);
}
ll res = minn;
for(int i = 0;i < zeros.size();i++){
int lpl = (i == 0)?l:zeros[i - 1] + 1;
int lpr = zeros[i] - 1;
res += solve(lpl,lpr);
if(i == zeros.size() - 1){
int rpl = zeros[i] + 1;
int rpr = r;
res += solve(rpl,rpr);
}
#ifdef dbg
debug(lpl);
debug(lpr);
#endif
}
return min(res,(long long)(r - l + 1));
}
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%d",&a[i]);
if(a[i] != 0){
if(l == -1){
l = r = i;
}else r++;
}else{
v.pb(mp(l,r));
l = -1;
}
}
if(l != -1)v.pb(mp(l,r));
for(int i = 0;i < v.size();i++){
pair<int,int> p = v[i];
l = p.fi,r = p.se;
ans += solve(l,r);
}
cout<<ans<<endl;
return 0;
}