HAUT1227 Flowers(贪心)

题目链接haut1227

题面

在这里插入图片描述

解题思路

贪心

这个问题的第一个关键点在于要发现:组成混合颜色的方案一定要优先于组成纯色的方案。因为组成混色方案更具鲁棒性。在相同资源下,组成三束分别不同颜色的花束一定也可以将其改成三束混合颜色的花束;而在小于三束混色花束的资源下却无法组成任何一束花。于是,我们大胆认为前者方案优于后者。

第二个关键点在于要发现:构成最大方案数的核心部分就是混合颜色的花束数量,因为当无法构成混合颜色花束时,问题就相当简单了,直接计算各自的纯色花束即可。而构成混合颜色花束数量取决于三种颜色中,花朵数量最小的那堆,所以我们先处理那堆最小的,处理完毕后再处理剩下的纯色的方案。

根据关键点二,我们容易形成一种错误的算法,就是把所有『最小堆』中的花朵全部都拿来构成混合颜色的花束,基于这个算法我们可以给出反例:2 7 7,这个样例正确答案应该是 5 ,也就是一个混合颜色花束加四束纯色花束,而不是上述算法所计算的 4 。

问题出在哪呢?这样的只形成局部最优而非全局最优的错误点不由得让人想直接去搜索,但是怎么搜索呢?根据关键点一的观点,我们可以考虑搜索『最小堆』的混合花束数量(实际上枚举就行了)。但是如果『最小堆』的花朵数量很多,那么我们这块的复杂度是相当爆炸的。我们发现在这种搜索策略下,『最小堆』中花朵的状态仅有三种:用于纯色、用于混色、闲置。而根据关键点一,当它能用于纯色时我们显然可以将其用混色替代。于是,状态就变成两种:混色、闲置。显然,当闲置了三个花朵我们肯定能将其至少组成一个纯色花束(其实还是可以转成混合颜色花束)。于是,这堆中,闲置花朵数量仅需考虑 0    1    2 0 \; 1 \; 2 012 ,最后取三种方案中最大的即可。

最后,我们再考虑『最大堆』『次大堆』剩下的花朵组成纯色花束。事实上,我们优先考虑混合颜色花束相当于是在切断三种颜色之间的相互约束,使得问题更简单而已。

可能我们还有个疑问,就是『最小堆』中最优情况下,那些闲置的花朵会不会有机会和其他颜色的花朵再构成混合花束?答案是否定的。因为我们枚举的这个最优情况实际上就是在最大程度利用其他两堆,使其能够减少闲置,更多地利用起来形成纯色花束,也就是说,最优情况下,其他两堆必然至少有一堆剩下的花朵全部都能构成纯色花束。

时间复杂度 O ( 1 ) O(1) O(1)空间复杂度 O ( 1 ) O(1) O(1)


实现代码

贪心
#include <bits/stdc++.h>

using namespace std;

int f(int r, int g, int b) {
    int m = min({r, g, b}), k = 0;
    for (int i = 0; i <= min(m, 2); i++) {
        k = max(k, m-i + (r-m+i)/3 + (g-m+i)/3 + (b-m+i)/3); //混合颜色 + 纯色
    }
    return k;
}

int main() {
    int red, green, blue;
    cin >> red >> green >> blue;
    cout << f(red, green, blue) << endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡同的诗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值