P2036 [COCI2008-2009 #2] PERKET

题目链接:

本题显然考查 \(\rm DFS\),但需注意是否恢复现场参数设置的细节。

image

#include <cstdio>
#include <algorithm>

const int N = 15;

struct Edge {
	int sour;
	int sweet;
}e[N];

bool st[N];//判断每个位置的数有没有被考虑过

int s = 1, t;//分别代表总的酸度和甜度
int ans = 0x3f3f3f3f, n;

void dfs(int u) {
	if (u > n) return;
	for (int i = 1; i <= n; i++) {
		if (!st[i]) {
			st[i] = true;
			s *= e[i].sour;
			t += e[i].sweet;
			ans = std::min(ans, abs(s - t));
			dfs(i + 1);
			st[i] = false;
			s /= e[i].sour;
			t -= e[i].sweet;//恢复现场
		}
	}
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d%d", &e[i].sour, &e[i].sweet);
	}
	
	dfs(1);
	printf("%d", ans);
	return 0;
}

但本题若是将总酸度和总甜度的参数设置在 \(\rm DFS\) 内,亦可以不恢复现场。
如果把变量设置为全局变量就需要手动回溯

#include <cstdio>
#include <algorithm>

const int N = 15;

struct Edge {
	int sour;
	int sweet;
}e[N];

int ans = 0x3f3f3f3f, n;

void dfs(int u, int s, int t) {
	if (u > n) {//表示所有的数都已经考虑完了
		if (s == 1 && t == 0) return;//判断清水的情况
		ans = std::min(ans, abs(s - t));
		return;
	}
	dfs(u + 1, s * e[u].sour, t + e[u].sweet);//选择当前数
	dfs(u + 1, s, t);//不选当前数
}

int main()
{
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d%d", &e[i].sour, &e[i].sweet);
	}
	
	dfs(1, 1, 0);
	printf("%d", ans);
	return 0;
}
posted @ 2024-04-02 09:21  胖柚の工作室  阅读(21)  评论(0)    收藏  举报