B. Moamen and k-subarrays

链接: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;
 	}
}

おすすめ

転載: blog.csdn.net/qq_43070117/article/details/119566800