1 条题解

  • 0
    @ 2026-4-25 15:33:30

    题解

    将猴子分为三个集合:

    • 集合 AA:只想坐第 11 排的 aa 只猴子。
    • 集合 BB:只想坐第 22 排的 bb 只猴子。
    • 集合 CC:无偏好的 cc 只猴子。

    教室有 22 排,每排 mm 个座位。我们需要最大化坐下的猴子数量,且必须满足有偏好猴子的要求。

    贪心策略的证明:

    如果第 11 排还有空位,并且集合 AA 中还有未安排的猴子,那么优先把集合 AA 的猴子安排到第 11 排一定是最优的。原因在于:集合 CC 的猴子可以坐到任意一排,而集合 AA 的猴子只能坐第 11 排。若我们优先用集合 CC 的猴子填充第 11 排,可能导致第 11 排被填满后,仍有集合 AA 的猴子无法入座,而此时第 22 排也许还有空位,但这些空位对于集合 AA 的猴子是无用的。这样就会造成座位浪费,无法达到最大数量。对称地,对于第 22 排和集合 BB 也是同样的道理。因此,全局最优的策略是:先尽可能满足有严格偏好的猴子,再用无偏好的猴子填充所有剩余座位

    算法步骤:

    1. 将集合 AA 的猴子安排到第 11 排,能坐下的数量为 min(m,a)\min(m, a)
      11 排剩余座位数为 r1=mmin(m,a)r_1 = m - \min(m, a)

    2. 将集合 BB 的猴子安排到第 22 排,能坐下的数量为 min(m,b)\min(m, b)
      22 排剩余座位数为 r2=mmin(m,b)r_2 = m - \min(m, b)

    3. 此时两排共剩余座位数:

      rem=r1+r2=2mmin(m,a)min(m,b)rem = r_1 + r_2 = 2m - \min(m, a) - \min(m, b)

      这些剩余座位可以任意分配给集合 CC 的猴子,能坐下的数量为 min(rem,c)\min(rem, c)

    4. 总答案即为三部分之和:

      ans=min(m,a)+min(m,b)+min(rem,c)ans = \min(m, a) + \min(m, b) + \min(rem, c)

    时间复杂度: 每组测试数据只需 O(1)O(1) 计算,总复杂度 O(t)O(t),完全可以通过 t104t \le 10^4 的数据范围。

    C++ 参考代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int tt;
        cin>>tt;
        while(tt--)
        {
            int m,a,b,c;
            cin>>m>>a>>b>>c;
            int ans=0,rem=0;
            ans+=min(m,a); rem+=m-min(m,a);
            ans+=min(m,b); rem+=m-min(m,b);
            ans+=min(rem,c);
            cout<<ans<<'\n';
        }
        return 0;
    }
    
    • 1

    信息

    ID
    6672
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者