题解:学而思编程 最小消耗
【题目来源】
学而思编程:最小消耗
【题目描述】
有 \(n\) 个怪兽等待你去消灭。
怪兽共分为两种形态,不妨用 \(0\) 和 \(1\) 来表示。
消灭一个 \(0\) 形态的怪兽需要耗费的法力值为 \(a\)。
消灭一个 \(1\) 形态的怪兽需要耗费的法力值为 \(b\)。
你还可以使用改造魔法将 \(0\) 形态怪兽改造为 \(1\) 形态或将 \(1\) 形态怪兽改造为 \(0\) 形态。
改造一个怪兽需要耗费的法力值为 \(c\)。
请问,将怪兽全部消灭最少需要耗费多少法力值。
【输入】
第一行包含整数 \(T\),表示共有 \(T\) 组测试数据。
每组数据第一行包含四个整数 \(n,a,b,c\)。
第二行包含一个长度为 \(n\) 的 \(01\) 字符串,其中的第 \(i\) 个字符表示第 \(i\) 个怪兽的初始形态。
【输出】
每组数据结果占一行,输出一个整数表示最小消耗
【输入样例】
3
4 1 2 1
1001
6 1 1 1
101011
3 2 1 3
111
【输出样例】
6
6
3
【核心思想】
-
问题分析:给定 \(n\) 个怪兽,每个怪兽有形态 \(0\) 或 \(1\)。消灭形态 \(0\) 消耗 \(a\),消灭形态 \(1\) 消耗 \(b\),改造一个怪兽消耗 \(c\)。求消灭所有怪兽的最小总消耗。这是一个贪心决策问题,关键在于对每个怪兽独立决策:直接消灭还是改造后再消灭。
-
算法选择:
- 独立贪心:每个怪兽的处理方式相互独立,分别计算两种形态的最优处理成本
- 最小值选择:对于每个怪兽,比较"直接消灭"和"改造后消灭"两种方案,取较小值
-
关键步骤:
- 初始化:读取 \(T\)(测试组数)
- 处理每组数据:
- 读取 \(n, a, b, c\) 和形态字符串 \(s\)
- 计算单怪兽最优成本:
kill0 = min(a, b + c):形态 \(0\) 的怪兽,直接消灭(成本 \(a\))或改造成 \(1\) 再消灭(成本 \(b + c\)),取较小值kill1 = min(b, a + c):形态 \(1\) 的怪兽,直接消灭(成本 \(b\))或改造成 \(0\) 再消灭(成本 \(a + c\)),取较小值
- 累加总成本:
ans = 0- 遍历 \(i\) 从 \(0\) 到 \(n-1\):
- 若
s[i] == '0':ans += kill0 - 否则:
ans += kill1
- 若
- 输出
ans
-
时间/空间复杂度:
- 时间复杂度:\(O(T \times n)\),每组数据线性遍历字符串
- 空间复杂度:\(O(n)\),存储形态字符串
-
独立贪心决策的核心思想:
- 怪兽间独立性:每个怪兽的改造和消灭决策不影响其他怪兽,总成本为各怪兽成本之和,无耦合约束
- 单怪兽最优即全局最优:由于无跨怪兽约束,每个怪兽取自身最小成本即可保证全局最小
- 两种策略对比:对每个怪兽只有两种选择(直接消灭当前形态 / 改造成另一形态再消灭),\(min\) 操作覆盖所有可能
- 改造的双向性:\(0 \to 1\) 和 \(1 \to 0\) 的改造成本相同(均为 \(c\)),但改造后的消灭成本不同,需分别计算
- 适用于"独立个体 + 二元选择"类问题,贪心策略将组合优化简化为每个元素的独立决策
【算法标签】
模拟
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int T;
string s;
int main()
{
cin >> T; // 读取测试用例数量
while (T--) // 处理每个测试用例
{
int n, a, b, c;
cin >> n >> a >> b >> c >> s; // 读取n, a, b, c和字符串s
int kill0 = min(a, b + c); // 处理字符'0'的最小花费
int kill1 = min(b, a + c); // 处理字符'1'的最小花费
int ans = 0; // 总花费
for (int i = 0; i <= n - 1; i++) // 遍历字符串s
{
if (s[i] == '0') // 如果字符是'0'
{
ans += kill0; // 加上处理'0'的最小花费
}
else // 如果字符是'1'
{
ans += kill1; // 加上处理'1'的最小花费
}
}
cout << ans << endl; // 输出总花费
}
return 0;
}
【运行结果】
3
4 1 2 1
1001
6
6 1 1 1
101011
6
3 2 1 3
111
3
浙公网安备 33010602011771号