洛谷 P1585 魔法阵 题解 qwq
作者:互联网
首先题目目害qwq
数据范围是 \(n\times m \le 50\) ,所以考虑搜索. 其实是因为这道题出现在搜索题单里
就是正常的搜索,题目中的起点在右上角,所以其实可以当起点在左上角来做,剪枝分可行性剪枝和最优性剪枝两种,可行性剪枝是判断是否处于一个单向通道中(上下走过左右没走过或上下没走过左右走过),最优性剪枝当然就是如果当前答案比最优答案大就可以直接不搜了。
细节处理有点多,但其实还好,调一会就调出来了。
const int NR = 55;
const int MR = 4e3 + 5;
int n, m, k1, k2;
int vis[NR][NR], px[MR], py[MR];
int ans = 1e9;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int calc(int x1, int y1, int x2, int y2) {
return k1 * abs(x1 - x2) + k2 * abs(y1 - y2);
}
void init() {
memset(vis, 1, sizeof(vis));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
vis[i][j] = 0;
}
}
vis[1][1] = 1;
}
void dfs(int x, int y, int s, int v) {
if (vis[x+1][y] && vis[x-1][y] && !vis[x][y+1] && !vis[x][y-1]) return ;
if (!vis[x+1][y] && !vis[x-1][y] && vis[x][y+1] && vis[x][y-1]) return ;
// cout << vis[x+1][y] << endl;
int res = 0;
if (s <= n * m / 2) {
px[s] = x; py[s] = y;
} else {
res = calc(x, y, px[s-n*m/2], py[s-n*m/2]);
}
if (v >= ans) return ;
if (s == n * m) {
ans = min(ans, max(v, res));
return ;
}
for (int i = 0; i < 4; i++) {
if (vis[x+dx[i]][y+dy[i]] == 0) {
vis[x+dx[i]][y+dy[i]] = 1;
dfs(x + dx[i], y + dy[i], s + 1, max(v, res));
vis[x+dx[i]][y+dy[i]] = 0;
}
}
}
int main() {
scanf("%d%d%d%d", &n, &m, &k1, &k2);
init();
dfs(1, 1, 1, 0);
cout << ans << endl;
return 0;
}
上课的时候老师讲这道题时我还在调上一道题,导致思路没有听见 TAT
然后大家做题的时候就直接摆烂,主动放弃,没有想到可行性剪枝 qwq
标签:剪枝,洛谷,int,题解,ans,vis,dx,dy,qwq 来源: https://www.cnblogs.com/milkycoffee/p/p1585-sol.html