New Year Parties
题意
n个人分布在一维坐标上,每个人可以左走一步xi-1,右走一步xi+1,或者原地不动xi,求通过此操作,最少占用坐标的点数和最多占用的点数分别是多少?
分析
求最小值:
因为最多只能将连续3个坐标的人,放在一个坐标上,所以从左往右扫描,如果i位置上有人,那么i,i+1,i+2就可以住一个房子,结果+1,然后i = i+3,继续同样的操作
求最大值:
从整体出发,先从左往右扫一遍,如果某个位置非空,但是左一个为空,就派一个人去占位,再从右往左扫描,如果某个位置非空,但是右边一个为空,就派一个人去占位。
所以整体上就形成了,整体尽量往左走一个,然后再整体尽量往右走一个,这样就更加能占更多位置
AC代码
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e6+10;
int N,resmin,resmax;
int mp[maxn];
int main(){
cin>>N;
int tmp;
for(int i = 0;i<N;i++){
scanf("%d",&tmp);
mp[tmp]++;
}
for(int i = 1;i<=N;){
if(mp[i]){
resmin++;
i = i+3;
}else i++;
}
for(int i = 1;i<=N;i++){
if(!mp[i-1] && mp[i]) mp[i-1]++,mp[i]--;
}
for(int i = N;i>=1;i--){
if(!mp[i+1] && mp[i]) mp[i+1]++,mp[i]--;
}
for(int i = 0;i<=N+1;i++) if(mp[i]) resmax++;
cout<<resmin<<" "<<resmax<<endl;
return 0;
} 
京公网安备 11010502036488号