链接:https://codeforces.com/contest/1557/problem/B
题意:将一个数组分成k份,将每一份视作一个整体重新排序,问是否存在一种顺序,使得整体数组有序。
思路:计算出将一个数组搞成有序至少需要将数组分成多少份,如果这个份数小于k,那么我们可以任意多分几个,更多的份数意味着更容易使数组有序。如果这个份数大于k,显然不行。
那么如何寻找这个最少的份数呢?
我们只需要将原数组中,不符合排序之后的数组的前后关系的子序列的个数求出即可:
例如 : 1 3 4 9 5 8对应着排序过后的数组1 3 4 5 8 9
显然最少的份数就是4,那么写法就比较好说了,用一个结构体或者map存一下每一个数对应前驱(因为数组里的数都不同),排完序之后再for一遍用cnt存一下几个前驱和map里存的前驱不同的,这个cnt就是最小份数。
或者 : 在map里存一下每个数的下标,排序过后for一遍,看下标是否连续(感谢凡佬 )
即 if(q[b[i]]!=q[b[i-1]]+1) cnt++;
细节 :
第一个数没有前驱,所以前驱初始化1e9+10
最小份数是1,所以cnt初始化为1(感谢凡佬 )
代码 :
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll ,ll>q;
ll a[100010];
ll b[100010];
int main()
{
int t;
cin>>t;
while(t--)
{
ll n,k;
cin>>n>>k;
a[0]=1e9+10;
for(int i=1;i<=n;i++)
{
cin>>a[i];
q[a[i]]=a[i-1];
}
sort(a+1,a+n+1);
ll cnt=1;
for(int i=2;i<=n;i++)
{
if(q[a[i]]!=a[i-1])
cnt++;
}
if(cnt>k)
{
cout<<"No"<<endl;
}
else cout<<"Yes"<<endl;
}
}