题意: 有n个人住在一些房子里,有的人住在同一个房子里。每个人可以选择搬去他的房子左边那个房子或者右边那个房子,亦或是不搬,搬只能向左或向右移动一次。问这些人最少住几个房子和最多住几个房子。
题解:最小值就是人尽可能聚合起来,节省房子空间数。最大值就是贪心地尽可能地向空房子移动,占据多的房子。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<stack> 7 #include <bitset> 8 #include<set> 9 #include<map> 10 #include<unordered_map> 11 #include<vector> 12 #include<cmath> 13 #include<string> 14 using namespace std; 15 typedef long long ll; 16 const int maxn = 2e5 + 5; 17 int x[maxn]; 18 int s[maxn]; 19 int n, t; 20 int main() { 21 cin >> n; 22 for (int i = 0; i < n; i++) { 23 cin >> t; 24 x[t]++; s[t]++; //记录那个房间有人,并且数量多少 25 } 26 int mx = 0, mi = 0; 27 //最大值就是使小朋友占据尽可能多的房子 28 for (int i = 1; i <= n + 1; i++) { 29 if (x[i] == 0) {//没人跳过 30 continue; 31 } 32 if (x[i - 1] == 0) {//前一个房子空着就移动过去 33 x[i]--; //因为占据尽可能多的房子,若本身为1,移动过去还是占据一个房子 34 x[i - 1]++; 35 } 36 if (x[i] > 1) {//因为该位置已经移动过一个,此时若还大于1,就可以往右再次移动 37 x[i + 1]++; 38 x[i]--; 39 } 40 } 41 //统计最大值 42 for (int i = 0; i <= n + 1; i++) { 43 if (x[i] != 0) { 44 mx++; 45 } 46 } 47 for (int i = 1; i <= n; i++) { 48 //若当前房子有人,则左右两边的人都会聚合 49 if (s[i] != 0) { 50 mi++; 51 i += 2; //加2再++相当于跳3 52 } 53 } 54 cout << mi << " " << mx << endl; 55 return 0; 56 }