题解:AT_arc226_b [ARC226B] Bin-ary Packing

· · 题解

题目分析

:::info[题意简化] 有 n 个背包与 m 种物品,第 0 \le i < m 中物品的重量为 2^i,个数为 a_i。物品最终需要全部装入背包里,背包的重量为背包里物品重量之和,合理分配物品的位置使得最重的背包最轻,求出最重的背包重量。 :::

初看题意,一种贪心策略悄然浮出水面。由于物品重量为整数,且根据题意,第 i 种物品的重量恰为i-1 种物品重量的两倍,这是解题的关键。将物品种类 im-10 枚举,每一轮枚举具体流程如下。

代码编写

#include <iostream>
typedef long long ll;
using namespace std;
const int M = 40;

// 单组测试数据的问题解决
inline void work() {
    // 变量定义与输入
    int n, m, a[M];
    cin >> n >> m;
    ll ans = 0, w = 0;
    for (int i = 0; i < m; i++)
        cin >> a[i];

    // 根据题解中的分析所进行的枚举,并执行题解中单次枚举的程序流程
    for (int i = m - 1; i >= 0; i--) {
        // 探寻物品数量与优惠额度的大小关系,并执行题解中的流程
        if (a[i] >= w)
            a[i] = a[i] - w, w = 0;
        else {
            w = 2 * (w - a[i]);
            continue;
        }

        // 探寻 a[i] 与 n 的整除性关系,并执行题解中的流程
        if (a[i] % n == 0)
            ans += (1ll << i) * (a[i] / n);
        else {
            int k = a[i] / n, b = a[i] % n;
            ans += (1ll << i) * (k + 1);
            w = 2 * (n - b);
        }
    }

    // 答案输出
    cout << ans << '\n';
}
int main(void) {
    int T;
    cin >> T;
    while (T--)
        work();
    return 0;
}

提交记录