专栏文章

题解:P10865 [HBCPC2024] Genshin Impact Startup Forbidden III

P10865题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqquas9
此快照首次捕获于
2025/12/04 09:14
3 个月前
此快照最后确认于
2025/12/04 09:14
3 个月前
查看原文
提供一篇搜索题解。

思路

观察题目发现 1k101 \le k \le 10 并且 ai3a_i \le 3,那么所有的有鱼的格点状态就只有 4k4^k 种,可以接受,所以我们可以定义一个 10 维数组来做状态减枝(我也是第一次定义那么多维的数组-_-||)。
然后就是怎么搜索了。我们枚举每个未被取完的有鱼的格子,要取到某个格子的鱼,我们可以有五个位置:上下左右中。枚举到一个格点 pip_i 后,我们也把 pip_i 的上下左右中减去我们要取的数量即可。

代码

CPP
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define PII pair<int, int>
#define x first
#define y second
#define cur (dp[arr[0]][arr[1]][arr[2]][arr[3]]\
[arr[4]][arr[5]][arr[6]][arr[7]][arr[8]][arr[9]])
int arr[15] = { 0 };
int dp[4][4][4][4][4][4][4][4][4][4] = { 0 };
int n, m, k;
PII pos[15];
int dir[5][2] = {
	{ 0, 0 }, { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }
};
void dfs(int step) {
	if (step >= cur) return;
	cur = step;
	vector<int> brr(k);
	for (int c = 0; c < k; c++)
		if (arr[c]) {
			int cnt = arr[c];
			for (int d = 0; d < 5; d++) {
				int x = pos[c].x + dir[d][0],
					y = pos[c].y + dir[d][1];
				for (int i = 0; i < 5; i++) {
					int dx = x + dir[i][0],
						dy = y + dir[i][1];
					for (int j = 0; j < k; j++)
						if (dx == pos[j].x && dy == pos[j].y) {
							brr[j] = arr[j];
							arr[j] = max(0, arr[j] - cnt);
						}
				}
				dfs(step + cnt);
				for (int i = 0; i < 5; i++) {
					int dx = x + dir[i][0],
						dy = y + dir[i][1];
					for (int j = 0; j < k; j++)
						if (dx == pos[j].x && dy == pos[j].y) arr[j] = brr[j];
				}
			}
		}
}
int main() {
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 0; i < k; i++) {
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		pos[i] = { x, y };
		arr[i] = z;
	}
	memset(dp, 0x3f, sizeof dp);
	dfs(0);
	printf("%d", dp[0][0][0][0][0][0][0][0][0][0]);
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...