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;
}
posted @ 2023-11-09 15:16  秦淮岸灯火阑珊  阅读(213)  评论(0编辑  收藏  举报