1 条题解

  • 0
    @ 2025-5-19 13:01:56

    题意分析

    题目描述了一个颜料套装购买问题,具体要求如下:

    1. 颜料套装

      • 每套包含3312125050毫升的不同颜色颜料。
      • 颜料可以单独使用,也可以通过混合三种不同颜色各XX毫升得到XX毫升灰色颜料。
    2. 需求输入

      • NN种颜色的需求量(毫升)。
      • 灰色颜料的需求量GG(毫升)。
    3. 目标

      • 计算满足所有颜色需求和灰色需求的最少套装数量。
      • 灰色颜料可以通过任意三种不同颜色的组合混合得到。

    示例解释

    第一个测试用例:

    • 颜色数N=3N=3,需求量分别为404095952121,灰色需求G=0G=0
    • 最大需求为9595,每套提供5050毫升,95/50=2\lceil 95 / 50 \rceil = 2套。
    • 输出22

    解题思路

    关键点分析

    1. 灰色颜料混合

      • 11毫升灰色需要消耗11毫升三种不同颜色。
      • 灰色需求GG会影响颜色的实际需求量。
    2. 套装计算

      • 每套提供5050毫升每种颜色。
      • 最少套装数由以下两者决定:
        • 单独颜色需求的最大值(考虑灰色消耗)。
        • 灰色需求GG对颜色消耗的额外要求。
    3. 数学建模

      • 设购买kk套,则每种颜色最多可用50×k50 \times k毫升。
      • 实际颜色需求为原始需求加上用于混合灰色的消耗。

    解决步骤

    1. 输入处理

      • 读取颜色数NN、各颜色需求和灰色需求GG
    2. 灰色消耗分配

      • 灰色需求GG需要从NN种颜色中分配,每种颜色最多贡献GG次(因每次混合需三种颜色)。
      • 最小化最大颜色需求量:max(颜色需求+灰色消耗)50×k\max(\text{颜色需求} + \text{灰色消耗}) \leq 50 \times k
    3. 二分搜索

      • 确定最少套装数kk的范围(下界max(颜色需求)/50\lceil \max(\text{颜色需求}) / 50 \rceil,上界(max(颜色需求)+G)/50\lceil (\max(\text{颜色需求}) + G) / 50 \rceil)。
      • 对于每个kk,检查是否能满足颜色和灰色需求。
    4. 验证kk的可行性

      • 计算每种颜色的剩余量:50×k原始需求50 \times k - \text{原始需求}
      • 剩余量总和3×G\geq 3 \times G(因每11毫升灰色消耗33毫升颜色)。
      • 每种颜色的剩余量\geq分配给灰色的量。

    算法复杂度

    • 时间复杂度:O(log(max_demand+G))O(\log (\max\_demand + G)),其中max_demand\max\_demand为最大颜色需求。
    • 空间复杂度:O(N)O(N),存储颜色需求。

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
     
    const int M=15;
    int p[M];
     
    bool cmp(int a,int b)
    {
        return a>b;
    }
     
    int main()
    {
        int n;
        int lea;
        int grey;
        int so;
        while(1)
        {
            lea=0;
            scanf("%d",&n);
            if(n==0)
                break;
            for(int i=0;i<n;i++)
            {
                 scanf("%d",&p[i]);
                 lea=max(lea,p[i]);
            }
            scanf("%d",&grey);
            if(lea%50==0)
                so=lea/50;
            else
                so=lea/50+1;
            for(int i=0;i<n;i++)
                p[i]=50*so-p[i];
            while(grey>0)
            {
                sort(p,p+n,cmp);
                if(p[2]==0)
                {
                    so++;
                    for(int i=0;i<n;i++)
                        p[i]+=50;
                }
                p[0]--;p[1]--;p[2]--;grey--;
            }
            printf("%d\n",so);
        }
        return 0;
    }
    
    • 1

    信息

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