手撸了几波小数据
容易发现最优解之一是所有人都按a[i]排序后再一段一段分开
如果不是这样的话,总会可以通过一些交换使之变成有序的
考虑dp,排序后f[i]=max{f[i-k]+1},k<=a[i],如果用两重循环的话时间貌似接受不了,用一个辅助数组g[]保存一下到当前位置的最大答案
#include<cstdio>
#include<algorithm>
#define N 1000005
using namespace std;
int read()
{
int a=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){a=a*10+c-'0';c=getchar();}
return a*f;
}
int n;
int a[N],f[N],g[N];
int main(void)
{
n=read();
for(int i=1;i<=n;++i) a[i]=read();
sort(a+1,a+n+1);
f[0]=g[0]=0;
for(int i=1;i<=n;++i)
{
if(i>=a[i]) f[i]=g[i-a[i]]+1;
g[i]=max(f[i],g[i-1]);
}
printf("%d",f[n]);
return 0;
}