[线性dp]Sending a Sequence Over the Network Codeforces1741E

The sequence aa is sent over the network as follows:

  1. sequence aa is split into segments (each element of the sequence belongs to exactly one segment, each segment is a group of consecutive elements of sequence);
  2. for each segment, its length is written next to it, either to the left of it or to the right of it;
  3. the resulting sequence bb is sent over the network.

For example, we needed to send the sequence a=[1,2,3,1,2,3]a=[1,2,3,1,2,3]. Suppose it was split into segments as follows: [1]+[2,3,1]+[2,3][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,3,2],
  • b=[1,1,3,2,3,1,2,2,3]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,2,3],
  • b=[1,1,2,3,1,3,2,3,2]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 bb is given. Could the sequence bb be sent over the network? In other words, is there such a sequence aa that converting aa to send it over the network could result in a sequence bb?

Input

The first line of input data contains a single integer tt (1≤t≤1041≤t≤104) — the number of test cases.

Each test case consists of two lines.

The first line of the test case contains an integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the size of the sequence bb.

The second line of test case contains nn integers b1,b2,…,bnb1,b2,…,bn (1≤bi≤1091≤bi≤109) — the sequence bb itself.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case print on a separate line:

  • YES if sequence bb could be sent over the network, that is, if sequence bb could be obtained from some sequence aa to send aa 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

input

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

output

YES

YES

YES

NO

YES

YES

NO

题意: 对于数组a,可以将其任意划分成若干段,对于每一段可以选择在其左侧或者右侧添加一个数字,这个数字就是这段长度,新构成的数组称为数组b,现在给出一个长度为n的数组b,问是否存在一个数组a能通过上述操作生成它。

分析: 设状态dp[i]表示区间[1, i]是否能通过某个数组得到,初始化全部为false,dp[0]为true,然后遍历b数组,对于每个位置其实就两种情况,一种是b[i]作为左侧区间的长度,一种是b[i]作为右侧区间的长度,对于b[i]是左侧区间长度情况,如果不会越界且dp[i-b[i]-1] == true,那dp[i] = true,对于另一种情况,如果不会越界且dp[i-1] == true,那么dp[i+b[i]] = true。当遍历到i的时候dp[i]就是能否根据某个数组得到区间[1, i]了,因为考虑最后一个分段,它的长度要么放在i位置,要么放在前面的某个位置,这两种情况之前都求出来了,所以可以得到答案。

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;

int a[200005];
bool dp[200005];

signed main()
{
	int T;
	cin >> T;
	while(T--){
		int n;
		scanf("%d", &n);
		for(int i = 1; i <= n; i++){
			scanf("%d", &a[i]);
			dp[i] = false;
		}
		dp[0] = true;
		for(int i = 1; i <= n; i++){
			//作为左侧区间长度 
			if(a[i]+1 <= i && dp[i-a[i]-1]) dp[i] = true;
			//作为右侧区间长度 
			if(i+a[i] <= n && dp[i-1]) dp[i+a[i]] = true;
		}
		if(dp[n]) puts("Yes");
		else puts("No");
	}
	return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值