给出一个数列(a_i),每次可以将一段前缀或一段后缀减一,问是否可以变成全(0)。
(nle 3*10^4)
显然这相当于将(a_i)拆成(x_i+y_i),满足(x_i)不递减,(y_i)不递增。
从后往前钦定(x_i)的值,记变量(pre)表示当前钦定到的最小值,初值为无限大。如果(a_i<pre)则(a_i)替换(pre);否则将(a_i)调整为(pre),并且将([1,i])区间同时减(a_i-pre)。按照这个策略,如果不出现负数就合法。
这个策略让当前(x_i)最大,并且(y_i)最小,给后面的区间预留了更多的空间,所以是对的。
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 30005
#define INF 1000000
#define ll long long
int n;
int a[N];
int main(){
// freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (int i=1;i<=n;++i)
scanf("%d",&a[i]);
if (n==1){
printf("YES
");
continue;
}
int pre=INF,cut=0;
bool bz=1;
for (int i=n;i>=1 && bz;--i){
a[i]-=cut;
if (a[i]<0)
bz=0;
if (a[i]<=pre)
pre=a[i];
else{
cut+=a[i]-pre;
a[i]=pre;
}
}
if (bz)
printf("YES
");
else
printf("NO
");
}
return 0;
}