Codeforces Round 428 (Div. 2) B. Game of the Rows
题面翻译
现在有 \(K\) 个队,飞机有 \(N\) 排座位,每排能坐 \(8\) 个人,不同队伍的人不能坐相邻的位置。
相邻情况有 \(5\) 种 \((1, 2), (3, 4), (4, 5), (5, 6), (7, 8)\)。请问这 \(n\) 排座位是否够坐。
(\(K\) 个队的总人数小于 \(8 \cdot N\))
【输入格式】
每组数据共两行。
第一行包含两个数 \(N,K\) 分别表示飞机有 \(N\) 排座位,有 \(K\) 个队伍(\(1 \le n \le 10000\),\(1 \le k \le 100\))。
第二行 有 \(k\) 个数字,\(a[1], \ldots, a[k]\),其中 \(a[i]\) 表示第 \(i\) 个队伍有 \(a[i]\) 人。
其中 \(a[1]+a[2]+ \cdots +a[K] \le 8 \cdot N\);
【输出格式】
如果这 \(n\) 排座位够坐,输出 YES
,否则输出 NO
。
思路
首先我们发现,有这样的两种座位。
中间四人座,和左右两边的双人座。
对于中间的四人座,它的使用方式为:一个小组的四人,或者两个小组(一组2人+另外一组1人)
对于两侧的双人座,它的使用方式为:一个小组2人,1个小组1人(退化为单人座)
座位使用率越高,越容易容纳所有小组,这是贪心的思想,所以我们
每个小组优先使用四人座,然后使用二人座,再用退化的单人座。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+20;
int n,k,a[N];
inline void init()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> k;
for (int i = 1; i <= k; i++)
cin >> a[i];
int cnt1 = n, cnt2 = n * 2, cnt3 = 0;
//cnt1表示4人座,cnt2表示为双人座,cnt3为单人座
for (int i = 1; i <= k; i++)
{
int cnt = min(cnt1, a[i] / 4);
cnt1 -= cnt;
a[i] -= 4 * cnt;
}
cnt2 += cnt1;//四人座改装为1个二人座+1个单人座
cnt3 += cnt1;
for (int i = 1; i <= k; i++)
{
int cnt = min(cnt2, a[i] / 2);
cnt2 -= cnt;
a[i] -= 2 * cnt;
}
//剩下的二人座都变成了单人座
cnt3 += cnt2;
int sum = 0;
for (int i = 1; i <= k; i++)
sum += a[i];
if (sum <= cnt3)
cout << "YES";
else cout << "NO";
}
signed main()
{
init();
return 0;
}