能量方块

题目传送门

整体思路:递归

我们可以两边递归,每次都是把这一段一直减,直到有一个变成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)。可以借助下面一个图来理解
111.png
那么这个题目就完美的解决了!

posted @ 2026-01-24 11:34  zhangruotian_Max  阅读(1)  评论(0)    收藏  举报