P4447 [AHOI2018初中组]分组 贪心
P4447 [AHOI2018初中组]分组
题解
在数轴上统计各个实力值出现的次数。我们要研究如何使人数最少的组别人数最大——也就是如何使长度最短的线长度最大。
不妨令每一次画线都从最左边一列开始。每次都画到底,可以吗?显然,大多数情况下这不是最优解。最后可能会剩下一个方块“一枝独秀”:
出现这种情况的根本原因是什么?我们发现,“一枝独秀”的方块总是出现在高度较高的几列。
如何解决?我们需要改变画线的方式:
如果右边一列的高度不低于当前列,则连接右边一列最下方的方块。反之,停止画线。
这样,最靠左的一个“峰”相较其右边一列的高度差就不断减小,直到相同。如此反复。记录所画所有线的最短长度,即为答案。
#include<bits/stdc++.h> using namespace std; int main() { map<int,int> m; int n; int ans=0x7fffffff; int cur=0; cin>>n; for (int i=1;i<=n;i++) { int x; cin>>x; m[x]++; } while(!m.empty()) { map<int,int>::iterator it,it1; it=m.begin(); it1=it; cur=1; it->second--; for (it1++;it1!=m.end()&&it->first+1==it1->first&&it->second<it1->second;it1++,it++) { cur++; it1->second--; } ans=min(ans,cur); it=m.begin(); while(it!=m.end()&&it->second==0) { int mf; mf=it->first; m.erase(mf); it=m.lower_bound(mf); } } cout<<ans<<endl; }