能量方块
整体思路:递归
我们可以两边递归,每次都是把这一段一直减,直到有一个变成0。然后就以这个点分两边递归,然后统计答案,在和r-l+1取min
那么代码如下
#include<bits/stdc++.h>
using namespace std;
int n,a[3001];
int solve(int l,int r,int c){
if(l>r) return 0;
int x=r-l+1;
int pos=l;
for(int i=l+1;i<=r;i++)
if(a[i]<a[pos])
pos=i;
x=min(x,a[pos]-c+solve(l,pos-1,a[pos])+solve(pos+1,r,a[pos]));
return x;
}
int main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
cout<<solve(1,n,0)<<endl;
}
Q:这个代码复杂度不是O(n³)吗,为什么可以通过?
A:其实代码的复杂度不是O(n³)
因为每一次都排除一个点,所以总共会有nlogn个区间,每一个区间是O(n)。那么最终的时间复杂度是O(n²logn)。可以借助下面一个图来理解

那么这个题目就完美的解决了!

浙公网安备 33010602011771号