题目
The sequence a is sent over the network as follows:
sequence a is split into segments (each element of the sequence belongs to exactly one segment, each segment is a group of consecutive elements of sequence);
for each segment, its length is written next to it, either to the left of it or to the right of it;
the resulting sequence b is sent over the network.
For example, we needed to send the sequence a=[1,2,3,1,2,3]. Suppose it was split into segments as follows: [1]+[2,3,1]+[2,3]. Then we could have the following sequences:
b=[1,1,3,2,3,1,2,3,2],
b=[1,1,3,2,3,1,2,2,3],
b=[1,1,2,3,1,3,2,2,3],
b=[1,1,2,3,1,3,2,3,2].
If a different segmentation had been used, the sent sequence might have been different.
The sequence b is given. Could the sequence b be sent over the network? In other words, is there such a sequence a that converting a to send it over the network could result in a sequence b?
Input
The first line of input data contains a single integer t (1≤t≤104) — the number of test cases.
Each test case consists of two lines.
The first line of the test case contains an integer n (1≤n≤2⋅105) — the size of the sequence b.
The second line of test case contains n integers b1,b2,…,bn (1≤bi≤109) — the sequence b itself.
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.
Output
For each test case print on a separate line:
YES if sequence b could be sent over the network, that is, if sequence b could be obtained from some sequence a to send a over the network.
NO otherwise.
You can output YES and NO in any case (for example, strings yEs, yes, Yes and YES will be recognized as positive response).
Example
inputCopy
7
9
1 1 2 3 1 3 2 2 3
5
12 1 2 7 5
6
5 7 8 9 10 3
4
4 8 6 2
2
3 1
10
4 6 2 1 9 4 9 3 4 2
1
1
outputCopy
YES
YES
YES
NO
YES
YES
NO
Note
In the first case, the sequence b could be obtained from the sequence a=[1,2,3,1,2,3] with the following partition: [1]+[2,3,1]+[2,3]. The sequence b: [1,1,2,3,1,3,2,2,3].
In the second case, the sequence b could be obtained from the sequence a=[12,7,5] with the following partition: [12]+[7,5]. The sequence b: [12,1,2,7,5].
In the third case, the sequence b could be obtained from the sequence a=[7,8,9,10,3] with the following partition: [7,8,9,10,3]. The sequence b: [5,7,8,9,10,3].
In the fourth case, there is no sequence a such that changing a for transmission over the network could produce a sequence b.
思路
- 模拟
从前往后枚举,枚举满足条件的边界,然后下一步 由边界+1进入更深一层的枚举(超时wa了) - dp
定义一个数组f[N],第i位为真 表示 i是满足条件的 段的右边界(每个段应该由 一个数字 n加n个数组成),
n必然是边界, 则f[n]为true时答案就为yes
代码
1 .模拟代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<unordered_map>
using namespace std;
const int N = 2e5 + 5;
int b[N];
int fa[N], fb[N];//以i 往前往后 作为 标记值,的 必达到得点
int n, t;
bool check(int now) {
if (now == n)return true;
if (fa[now + 1] && fa[now + 1] <= n) {
bool is = false;
is = check(fa[now + 1]);
if (is)
return true;
}
for (int i = now + 2; i <= n; i++) {
if (fb[i] == now + 1) {
bool is = check(i);
if (is)
return true;
}
}
return false;
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &b[i]);
if (i + b[i] <= n)fa[i] = i + b[i];
else fa[i] = 0;
if (i - b[i] >= 1)fb[i] = i - b[i];
else fb[i] = 0;
}
if (check(0))
puts("YES");
else
puts("NO");
}
return 0;
}
2 .动态规划代码
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int N=2e5+5;
int a[N];
void solve(){
int n;
scanf("%d",&n);
// 定义 f[N]为满足条件的边界,且为you边界
vector<bool>f(n+1,false);
f[0]=true;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
// 作为前缀
if(f[i-1]&&a[i]+i<=n)f[a[i]+i]=true;
// 作为后缀
if(i-a[i]>=1&&f[i-a[i]-1]==true)f[i]=true;
}
if(f[n])
puts("YES");
else
puts("NO");
}
int main(){
int t;
cin>>t;
while (t--){
solve();
}
return 0;
}