直接贪心即可.
1.首先考虑max,什么时候能取到max呢?显然是直接统计下每个位子的数量,然后数量大于>=3那么直接标记3个位子,假如是2那就看下左边有没有被标记,我们从左到右一个一个考虑嘛.假如没有被标记,那么显然是要标记左边和自身的,假如标记了,那么我就标记右边和自身,假如只有一个的话,就是看看自己的左边有没有标记,再看看自身有没有被标记,假如都被标记了,就标记右边呐...然后从头到尾扫一遍就完事.
2.然后考虑min,什么时候取到min呢?假如把max看作一个分散的过程,那么min就是一个整合的过程,差值为2的区间都可以合并为1,然后貌似统计下就完事...
代码如下:
#include <bits/stdc++.h> using namespace std; const int N=2e5+5; int a[N],cnt[N]; int vis1[N],vis2[N]; int p1[N],p2[N]; int main() { int n;scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); cnt[a[i]]++;} sort(a+1,a+1+n);int ans2=0; for(int i=1;i<=n;i++) { if(p1[a[i]]) continue; if(cnt[a[i]]>=3) { vis1[a[i]-1]=1; vis1[a[i]]=1; vis1[a[i]+1]=1; } else if(cnt[a[i]]==2) { if(vis1[a[i]-1]==1) { vis1[a[i]]=1; vis1[a[i]+1]=1; } else { vis1[a[i]]=1; vis1[a[i]-1]=1; } } else { if(vis1[a[i]-1]==1&&vis1[a[i]]==0) { vis1[a[i]]=1; } else if(vis1[a[i]-1]==1&&vis1[a[i]]==1) { vis1[a[i]+1]=1; } else if(vis1[a[i]-1]==0) { vis1[a[i]-1]=1; } } p1[a[i]]=1; } for(int i=0;i<=n+1;i++) { if(vis1[i]) ans2++; } //cout<<ans2<<endl; //max int ans1=1,pos=a[1]; for(int i=1;i<=n;i++) { if(p2[a[i]]) continue; if(a[i]>pos+2) {ans1++,pos=a[i];} p2[a[i]]=1; } //min printf("%d %d\n",ans1,ans2); return 0; }