Yuulis.log

トンネルを抜けるとそこは参照エラーであった。

【AtCoder】ABC 338 C - Leftover Recipes | 茶コーダーが解くAtCoder

atcoder.jp

実行時間制限: 2 sec / メモリ制限: 1024 MB / Difficulty: 513

問題概要

いま、  N 種類の材料があり、材料  i Q_i グラムある。これらの材料を使って2種類の料理 A, B を作ることを考える。料理 A には一人分に各材料が  A_i グラム必要で、料理 B には一人分に各材料が  B_i グラム必要である。このとき、最大で計何人分の料理を作ることができるかを求めよ。

制約

  • 入力はすべて整数。
  •  1 \leq N \leq 10
  •  1 \leq Q_i \leq 10^6
  •  0 \leq A_i, B_i \leq 10^6

考察

料理 A, B をそれぞれ  a, b 人分作ることにする。単純に考えると  a, b を全探索して、すべての  i (1 \leq i \leq N) に対し  A_ia + B_ib \leq Q_i を満たすかどうかを判定していけばよい。だが、2つの料理は最大で  10^6 人分作れる (例えば、  Q_i = 10^6, A_i = 1 のときなど) ので、これでは間に合わない。

ここで、  a, b のいずれかを固定したときに、もう一方は即座に決まることに注目してみよう。

例えば、  a = a_0 と固定したとき、各  i に対して残りの材料  rest_i rest_i = Q_i - A_ia_0 であり、このとき最大で  \lfloor \frac{rest_i}{B_i} \rfloor 人分の料理を作ることができる。

このようにして求めた  \lfloor \frac{rest_i}{B_i} \rfloor の最小値が、結果的に作ることができる料理 B の最大値 (コード中のmax_b) である (これより小さい  b はすべての  i に対し  A_ia + B_ib \leq Q_i を満たす) 。

また、 a についても作ることができる料理 A の最大値 (コード中のmax_a) を求めておく。

最終的な答えは、  0 \leq a \leq \max a で走査したときの  \max a + \max b の最大値となる。

コード

#include <bits/stdc++.h>
using namespace std;

#define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++)

bool chmax(T &a, const T &b)
{
    if (a < b)
    {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b)
{
    if (b < a)
    {
        a = b;
        return 1;
    }
    return 0;
}

// ======================================== //

int main()
{
    int N;
    cin >> N;
    vector<int> Q(N), A(N), B(N);
    rep(i, 0, N) cin >> Q[i];
    rep(i, 0, N) cin >> A[i];
    rep(i, 0, N) cin >> B[i];

    int max_a = INF;
    rep(i, 0, N) if (A[i] > 0) chmin(max_a, Q[i] / A[i]);

    int ans = 0;
    rep(a, 0, max_a + 1)
    {
        int max_b = INF;
        rep(i, 0, N)
        {
            int rest = Q[i] - A[i] * a;

            if (B[i] > 0)
                chmin(max_b, rest / B[i]);
        }
        chmax(ans, a + max_b);
    }

    cout << ans << endl;
}

atcoder.jp

実装時間: 30分

結果的には片方を固定する全探索なのだが、「最小値を最大値とする」という考えは混乱しやすいかも。