Description
Example
input
4
3
1 2 1
5
11 7 9 6 8
5
1 3 1 3 1
4
5 2 1 10
output
YES
YES
NO
YES
Solution
这题显然可以转化为,构造两个长度为n的序列a,b, 其中 a为非递增,b为非递减,且
v
i
=
a
i
+
b
i
v_i = a_i + b_i
vi=ai+bi
对于
a
i
a_i
ai,需满足:
①
a
i
<
=
a
i
−
1
a_i <= a_{i-1}
ai<=ai−1
②
v
i
−
a
i
>
=
b
i
−
1
v_i - a_i >= b_{i-1}
vi−ai>=bi−1
得 a i < = m i n ( v i − b i − 1 , a i − 1 ) a_i <= min(v_i-b_{i-1}, a_{i-1}) ai<=min(vi−bi−1,ai−1)
显然可以贪心的使得 a i a_i ai尽可能大
Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e4 + 7;
int num[maxn];
int a[maxn], b[maxn];
bool solve(int n) {
for(int i = 1;i <= n;++i) a[i] = b[i] = 0;
a[1] = num[1], b[1] = 0;
for(int i = 2;i <= n;++i) {
a[i] = min(num[i]-b[i-1], a[i-1]);
b[i] = num[i] - a[i];
}a[0] = 1e9;
for(int i = 1;i <= n;++i) {
if(a[i]>a[i-1] || a[i] < 0 || a[i] > num[i] || a[i] + b[i] != num[i]) return false;
}b[n+1] = 1e9;
for(int i = n;i >= 1;--i) {
if(b[i]>b[i+1] || b[i] < 0 || b[i] > num[i]) return false;
} return true;
}
int main() {
int T;scanf("%d",&T);
while(T--) {
int n;scanf("%d",&n);
for(int i = 1;i <= n;++i) {
scanf("%d",&num[i]);
}
if(n < 3) printf("YES\n");
else {
bool res = solve(n);if(res) printf("YES\n"); else printf("NO\n");
}
}
return 0;
}