不知道为什么洛谷上没有这道题。。。
题目大意
给出 \(n\) 个数,分别为 \(a_1,a_2,\cdots,a_n\)。
\(a_i\) 表示第 \(i\) 个箱子上最多能 叠 \(a_i\) 个箱子。
叠是指这样:
形如上图这样的我们称为一堆。
求最少需要多少堆把所有箱子都叠起来。
题目分析
考虑贪心。
我们可以先将 \(a\) 数组升序排列。
对于每个数,我们依次遍历所有数,如果有一个箱子能够叠在当前这一堆的最下面(即 \(a_i\) 大于当前这一堆箱子数量),那么立刻处理,并且删除掉这个数。
答案就是能够进行多少次这个操作。
我们如果使用数组的话,非常不方便完成删除操作,所以可以使用 \(\rm STL\) 里的 multiset
。
代码
//2021/11/17
//2021/11/18
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <climits>//need "INT_MAX","INT_MIN"
#include <set>
#define enter() putchar(10)
#define debug(c,que) cerr<<#c<<" = "<<c<<que
#define cek(c) puts(c)
#define blow(arr,st,ed,w) for(register int i=(st);i<=(ed);i++)cout<<arr[i]<<w;
#define speed_up() std::ios::sync_with_stdio(false)
namespace Newstd
{
inline int read()
{
char c;
bool flag=false;
while((c=getchar())<'0' || c>'9')
{
if(c=='-') flag=true;
}
int res=c-'0';
while((c=getchar())>='0' && c<='9')
{
res=(res<<3)+(res<<1)+c-'0';
}
return flag?-res:res;
}
inline void print(int x)
{
if(x<0)
{
putchar('-');x=-x;
}
if(x>9)
{
print(x/10);
}
putchar(x%10+'0');
}
}
using namespace Newstd;
using namespace std;
int n;
multiset<int>st;
int main(void)
{
n=read();
for(register int i=1;i<=n;i++)
{
int x=read();
st.insert(x);
}
int ans(0);
while(!st.empty())
{
int cnt(0);
multiset<int>::iterator it=st.begin();
while(it!=st.end())
{
if((*it)>=cnt)
{
cnt++;
st.erase(it++);
}
else
{
it++;
}
}
ans++;
}
printf("%d\n",ans);
return 0;
}