【看了官方题解后补题写出

思路 不使用魔法容易分析,使用魔法时, 假设对 ar[i] ar[i+1] 使用魔法,即直接消灭怪物(ar[i]=0,ar[i+1]=0) 那么,需要的花费即为 处理前 i-1 个怪物与 后 i+2个 的总和 (i,i+1 已经处理完毕)

预处理 因此,先按照顺序处理 pre[i] 含义为 从 0 到 i 需要的花费 再按照逆序,处理bac[i] 含义为 从 n-1 到 i+2 的费用 都是左闭右闭的区间

贪心 先考虑 i=0 i=n-2 即 在首尾位置释放魔法的情况 再考虑普通情况

using namespace std;
#define For(n) for(int i=0;i<n;i++)
#define int long long
#define L 1000005
int pre[L],bac[L],ar[L],br[L];
signed main()
{
    int n;cin>>n;
    for (int i=0;i<n;i++)
    {
    	cin>>ar[i];br[i]=ar[i];
	}
	if(n<3)//注意,此时数量较少 1/2 可以利用魔法直接完成
	{
		cout<<0<<endl;return 0;
	}
	int d=ar[0];
	
	for (int i=0;i<n-2;i++)//预处理pre
	{
		d=max(0ll,ar[i]);//这里使用 0ll  是为了类型匹配
		if (i)pre[i]=pre[i-1]+d;
		else pre[i]=d;
		ar[i]=0;
		ar[i+1]-=d;ar[i+2]-=d;
	}
	for (int i=n-1;i-2>=0;i--)//预处理bac
	{
		d=max(0ll,br[i]);
		if (i!=n-1)		bac[i]=bac[i+1]+d;
		else {
			bac[i]=d;
		}
		br[i]=0;br[i-1]-=d;br[i-2]-=d;
	}
	
    //贪心的处理
	int ans=bac[2];
	ans = min(ans, pre[n-3]);
	//考虑 首尾的情况
	for (int i=1;i<n-2;i++)
	{
		ans=min(ans,pre[i-1]+bac[i+2]);//获取最小的费用
	}
	cout<<ans<<endl;
	
	return 0;
}