K-Bag(DP)
思路:
。
考虑:令
点
能否别切割,即前
个数能否成为一个
序列。
这一步可以用 记数统计,需要注意的是当 时需要将前 个数是否为一个部分序列考虑进去,其他情况只用考虑 个数。
然后从后往前扫最多 个数,判断 和 同时成立,若存在则成立。
时间复杂度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a) memset(a,0,sizeof a)
int t,n,k,a[N],cnt,ok;
bool dp[N];
unordered_map<int,int>mp;//用map会T.
bool solve(){
mp.clear(),cnt=0;
memset(dp,false,sizeof dp);
dp[0]=true;
for(int i=1;i<=n;i++){
if(i>k) if(!--mp[a[i-k]]) cnt--;
if(!mp[a[i]]++) cnt++;
if(cnt==k||cnt==i) dp[i]=i-k>=0?dp[i-k]:1;
}
mp.clear(),cnt=0;
for(int i=n;i>=max(n-k,0);i--){
if(dp[i]&&cnt==n-i) return true;
if(!mp[a[i]]++) cnt++;
}
return false;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
ok=1;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]>k||a[i]<1) ok=0;
}
if(!ok){
puts("NO");continue;
}
puts(solve()?"YES":"NO");
}
return 0;
}