P4447 [AHOI2018初中组]分组

实在想不出来,就看了题解

这位大牛的题解

我拜读是ZgZhIWn的博文,看了他的思路,技巧性太强了,除了佩服还能说些什么呢卧槽,这也太妙了 看了这篇题解之后我有两个疑问:
1 :在P数组中,为什么具有相同的下一个成员的实力值,下标越大,组的长度越小呢?也就是有p[i]==p[j] (i<j)为什么有siz[i]>=siz[j]呢
答:我想了想,然后找了实例手动跑了一下,原因就在我们将f数组按照递增排了序,一个f[x],要么被接在了前面某一个组的后面,要么成为了一个新开的组的第一个。在问题中,有第i组的第一个实力值<=第j组的第一个实力值,就像连个连续的序列,有同样的末尾值,当然是起始值大的长度小了
2:对p数组为甚么可以用lower_bound()函数,p 数组是递增的吗?
答:p数组确实是递增的(非严格)的,因为对于f[i],我们总是将其接到f[i]==p[x],x最大的那一组,这就保证了p数组是递增的
提供一组样例,可以模拟一下,N=8实力值依次是
1 2 3 3 4 4 4 5
#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
#define pi acos(-1.0)
#define e exp(1.0)
const ll maxn=1e5+7;
ll f[maxn],top,siz[maxn],p[maxn];
//f[]:存放输入数据,p[i]:第i个组下一个可以连接的经验值,s[i]:第i个组的长度,top:组的个数 
int main()
{
//  freopen(".../.txt","w",stdout);
	ios::sync_with_stdio(false);
	ll N,i,j;
	cin>>N;
	for(i=1;i<=N;i++)
	cin>>f[i];
	sort(f+1,f+N+1);
	top=0;
	memset(siz,0,sizeof(siz));
	for(i=1;i<=N;i++)
	{
		ll pos1=lower_bound(p+1,p+top+1,f[i])-p; 
		ll pos=upper_bound(p+1,p+top+1,f[i])-p;
		if(pos1!=top+1&&pos>pos1)//在P数组中找到值为f[i]并且下标最大的那个(长度最小),将该值连接到这一组上,
		//这种方式正好满足最大化最小长度的要求 
		{
			p[pos-1]++;
			siz[pos-1]++;
		}
		else
		{
			p[++top]=f[i]+1;
			siz[top]=1;
		}
	}
	ll res=1e9;
	for(i=1;i<=top;i++)
	res=min(res,siz[i]);
	cout<<res<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值