https://codeforces.com/problemset/problem/1381/B
这题只会n^3,掉大分。hwh:这不是显然的结论吗,人尽皆知啊
我们判断是否可以组成满背包
优先拿更短的物品去更新,如果更短的物品跟更长物品,可以只考虑这个更短的物品,也就是说,分组背包中一个组内,只考虑最短的物品就更新背包容量dp数组会更容易得到更多的位置能被组成。
要知道这题的结论就是下一段数的首数字要大于上一段数字的全部,而且序列分段是连续不重叠的,于是如果能够1-2,1-3,1-4,那么必然可以1-3,4-4,所只要找到最近的能更新的部分去刷新dp数组就可以了。所以整个区间最多被贪心地分成n段,所以一共只有n个物品,且互不冲突
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxl=4010;
int n,m,cas,k,cnt,tot,ans;
int a[maxl];
bool dp[maxl];
char s[maxl];
bool in[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=2*n;i++)
scanf("%d",&a[i]);
}
inline void mainwork()
{
a[2*n+1]=2*n+1;dp[0]=true;
for(int i=1;i<=n;i++) dp[i]=false;
int mx,len;
for(int i=1;i<=2*n;i++)
{
mx=a[i];
for(int j=i;j<=2*n;j++)
{
mx=max(a[j],mx);len=j-i+1;
if(a[j+1]>mx)
{
for(int w=n;w>=len;w--)
dp[w]|=dp[w-len];
i=j;
break;
}
}
}
}
inline void print()
{
if(dp[n])
puts("YES");
else
puts("NO");
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}