P4505 [CTSC2013]组合子逻辑 贪心+优先队列

题意:

给定一个长度为n序列,可以给序列任意两数(可以不相邻)外层加上一对括号,要求每对括号内元素个数不能超过第一个元素大小,求最少能加几层括号包含所有数

范围&性质:\(1\le n\le 2*10^6\)

分析:

贪心的想,肯定越大的数能包含的数就越多,且要包含所有的数,那么至少在第一个数前面加上一个括号,之后不能添加时,就从已经在括号内的数中选择最大的一个数继续添加括号,接管原有的一部分,让最外层继续扩展,可以通过优先队列实现

代码:

#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
	const int maxn = 2e6+5;
	int t,ans;
	int n,a[maxn]; 
	priority_queue<int> q;
	
	void work()
	{
		scanf("%d",&t);
		while(t--)
		{
			int x;
			scanf("%d",&n);
			if (n==1)
			{
				scanf("%d",&x);
				if(x==0) printf("-1\n");
				else printf("0\n");
			} 
			else
			{
				for (int i=1; i<=n; i++)
				{
					scanf("%d",&a[i]);
				} 
				int tmp=a[1]-1;
				ans=1;
				while (!q.empty()) q.pop();
				for (int i=2; i<=n; i++)
				{
					if (tmp) tmp--; 
					else
					{
						if(q.empty()||q.top()<=1)
				    	{ 
						   	ans=-1; 
						   	break; 
						}
						ans++;
						tmp=q.top()-2;
						q.pop();
					}
					q.push(a[i]);
				}
				printf("%d\n",ans);
			}
		}
	}

}

int main()
{
	zzc::work();
	return 0;
}
posted @ 2020-09-14 16:15  youth518  阅读(161)  评论(3编辑  收藏  举报