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

posted @ 2022-08-24 20:10  liangbowen  阅读(16)  评论(0编辑  收藏  举报