题意:
给你长度为2*n的p数组,p数组是根据a数组和b数组在规则下产生的
规则
ai<bi 将ai放到p数组,在a数组中删除ai
ai>bi 将bi放到p数组,在b数组中删除bi
现在问你根据p数组,能否判断出是由两个长度为n的数组组成的
解析:
如果a[l~r] <b[i] 那么我们肯定优先选择a[l~r] 这一段
同理 a[i]>b[l~r] 那么我们肯定优先选择b[l~r]这一段
根据这个性质 我们从p[1]开始往后找第一个大于p[1]的数,我们给这块区间分段
例如 样例1
2 3 1 4
第一个大于2的是3 所以2单独分成一段
第一个大于3的是4 所以(3,1)分成一段
4后面没有数了,4就是单独一段
(2),(3,1),(4)
每一段的价值就是这一段的长度
通过01背包,求出背包容量为n最大价值也为n 就是YES
如果最大价值不为n 输出NO
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+1000;
int t,n;
int a[N],v[N];
int f[N];
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=2*n;i++) scanf("%d",&a[i]);
memset(f,0,sizeof f);
int cnt=1;
int tot=0;
int tmp=a[1];
for(int i=1;i<=2*n;i++)
{
if(a[i]<tmp) cnt++;
else if(a[i]>tmp)
{
v[++tot]=cnt;
cnt=1;
tmp=a[i];
}
}
for(int i=1;i<=tot;i++)
for(int j=n;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+v[i]);
if(f[n]==n) puts("YES");
else puts("NO");
}
}