AT4302 题解
小学生来写题解啦!
先看数据范围,都很小,并且时间有两秒,因此选择暴力搜索,即深度优先搜索。
先将竹子分配给目标竹子使用。
想象你是一根竹子,你可以去选择为三根目标竹子做贡献,或不使用自己。
分配完每根竹子的工作后,就计算魔法值。
虽然有多种方法制作目标竹子,但魔法值是一样的。
所以,我们可以先将所有竹子合成一根,再通过延长或缩短达到目标长度。
送上AC代码
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int n, A, B, C, minn = 2e9;
int h[10];
void dfs(int x, int a, int b, int c, int cnt)
//当前递归到第 x 根竹子。
//现在三根目标竹子分别有 a, b, c厘米的竹子。
//已经使用了 cnt 次合成魔法。
{
if (x > n)
{
if (a != 0 && b != 0 && c != 0) //特判!至少得有竹子才能制作!
{
int mp = cnt * 10;
mp += abs(a - A);
mp += abs(b - B);
mp += abs(c - C);
minn = min(minn, mp);
}
return;
}
//A
dfs(x + 1, a + h[x], b, c, cnt + (a != 0));
//B
dfs(x + 1, a, b + h[x], c, cnt + (b != 0));
//C
dfs(x + 1, a, b, c + h[x], cnt + (c != 0));
//不要
dfs(x+1, a, b, c, cnt);
}
int main()
{
scanf("%d%d%d%d", &n, &A, &B, &C);
for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
dfs(1, 0, 0, 0, 0);
printf("%d", minn);
return 0;
}
还有一个值得提出的点。
我代码的效率远远超出了我的想象。
我没做优化,但最高的点也仅有八毫秒。
首发:2022-01-25 10:56:55