CF839B 飞机选座

1 CF839B 飞机选座

2 题目描述

时间限制 \(1s\) | 空间限制 \(256M\)

\(Daenerys\ Targaryen\) 有一支由 \(k\) 组战士组成的部队,第 \(i\) 组有 \(a_i\) 个战士。她想带她的战士们去大海的对面去征服铁王座。她最近买了一个飞机来运载她的战士过海。这个飞机有 \(n\) 排,每一排有 \(8\) 个座位。定义这几个位置对为邻居:\(\{1, 2\}, \{3, 4\}, \{4, 5\}, \{5, 6\}\), \(\{7, 8\}\)\(Daenerys\ Targaryen\) 只想让同一组的战士坐在邻居的位置上。请帮助确定她是否可以做到。

数据范围:\(1 ≤ n ≤ 10000, 1 ≤ k ≤ 100\)

3 题解

贪心:我们先考虑安排 \(4\) 人座,这是因为 \(4\) 人座容纳的人更多。如果我们选择先安排 \(2\) 人座,会导致 \(4\) 人座被浪费。在安排完 \(4\) 人座后,如果还有剩余的 \(4\) 人座,那么我们将这些 \(4\) 人座拆成一个 \(2\) 人座和一个 \(1\) 人座。这样可以最大化我们每一个座位的利用率。随后我们只需要将所有 \(2\) 人座安排给军队即可。如果剩下一部分 \(2\) 人座,那么我们可以将这些 \(2\) 人座当做 \(1\) 人座用。这是由于如果我们在某个 \(2\) 人座上安排了一个人,那么我们无法再安排任何其他军队的人。

如果我们在最后分配 \(1\) 人座的时候发现某一步没有足够的 \(1\) 人座供军队乘坐,那么我们就一定不能构造出可行方案,否则一定可以。

4 代码(空格警告):

#include <iostream>
using namespace std;
const int N = 1e5+10;
const int K = 105;
int n, k, four, two, Mod, one;
int a[N];
int main()
{
    cin >> n >> k;
    for (int i = 1; i <= k; i++) cin >> a[i];
    four = n;
    two = n*2;
    for (int i = 1; i <= k; i++)
    {
        if (four >= (a[i]/4))
        {
            four -= a[i] / 4;
            a[i] -= (a[i] / 4) * 4;
        }
        else
        {
            a[i] -= four * 4;
            four = 0;
        }
    }
    two += four;
    for (int i = 1; i <= k; i++)
    {
        if (two >= (a[i] / 2))
        {
            two -= a[i] / 2;
            a[i] -= (a[i] / 2) * 2;
        }
        else
        {
            a[i] -= two * 2;
            two = 0;
        }
    }
    one += two + four;
    for (int i = 1; i <= k; i++)
    {
        one -= a[i];
        if (one < 0)
        {
            cout << "NO";
            return 0;
        }
    }
    cout << "YES";
    return 0;
}

欢迎关注我的公众号:智子笔记

posted @ 2021-03-30 22:18  David24  阅读(38)  评论(0编辑  收藏  举报