F- Kobolds and Catacombs_gov

思路:

(1)对于一个数列,要求尽可能多的分组,使得组内排序后得到非递减数列。

(2)注意到排序后数列是唯一的,于是对比原数列与排序后数列;

(3)只要保证组内原现数列的元素相同,并使得数量尽可能少,可以考虑在某一时刻,保证原数列最大值与最小值分别与排序数列相同时截断分组但是此时不足以保证组内元素相同;也可考虑维护一个l,r前缀和恰好相同时截断分组,l = r + 1,r = l;否则r ++;由b的单调性易证前缀和相同时元素必然相同。

代码:

#include

using namespace std;

const int N = 1e6 + 10;
typedef long long LL;
LL a[N],b[N],sa[N],sb[N];


int main()
{
    int n;
    cin >> n;
    
    for(int i = 1;i <= n;i ++)
    {
    	cin >> a[i];
    	sa[i] = sa[i - 1] + a[i];
	}
    	
    memcpy(b,a,sizeof a);
    
    sort(b + 1,b + n + 1);
	
	for(int i = 1;i <= n;i ++)
	{
		sb[i] = sb[i - 1] + b[i];
	}
	LL res = 0;
	int l = 1;
	for(int r = 1;r <= n;)
	{
		if(sa[r] - sa[l - 1] == sb[r] - sb[l - 1])
		{
			res ++;
			l = r + 1;
			r = l;
		}
		else
		{
			r ++;
		}
	}
	
	cout << res << endl;
    return 0;
}


你可能感兴趣的:(算法,数据结构)