其他分享
首页 > 其他分享> > 洛谷 P1585 魔法阵 题解 qwq

洛谷 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