題目連結: https://tioj.ck.tp.edu.tw/problems/1034

# 內容

米勒上尉收到一道緊急命令,要求將二等兵雷恩即刻護送至指定地點。米勒上尉馬上攤開戰場地圖,希望能規畫出一條最安全的路線。戰場地圖可視為一個 N×N 的表格,表格中的每個位置只可以往東、南、西、北四個鄰近的位置移動。根據情報,米勤上尉已經掌握每個位置的敵軍兵力,所謂最安全的路線,指的是這條路線上所有敵軍兵力總和最小的路線。米勒上尉可以用「一發」死光炸彈轟炸地圖上的「一個」位置,轟炸過後該位置的敵軍將灰飛湮滅,幫助米勒上尉找出在一發死光炸彈支援下,最安全路線的敵軍兵力總數。

# 思路

這題因為可以轟掉一格,所以用 DP 做不好做,仔細想想我們如果可以快速得到任意兩點的最短距離的話,那就直接枚舉炸掉所有位置,看看哪樣比較短就好了啊。式子就會轉換成 ans = min {dis [a][k] + dis [k][b]-val [k]} 這樣的話,用學過的 floyed-warshall 就好啦!
不過說直接 floyd-warshall 很容易,但本題給的是點權,可能沒辦法好好做,所以就要將輸入進來的數上下左右做出連結,而座標的話... 用 Hash 轉換一下就好啦

# 程式碼

#include <bits/stdc++.h>
using namespace std;
#define maxn 405
int N, Q, x,y, x2, y2;
int val[maxn], dis[maxn][maxn], minn;
inline int Hash(int x, int y){
    return x * N + y;
}
int main() {
    while(cin >> N){
        for (int i = 0; i < maxn; i++){
            for (int j = 0; j < maxn; j++){
                if (i == j) dis[i][j] = 0;
                else dis[i][j] = 0x3FFFFFFF;
            }
        }
        //transform
        for (int i = 0; i < N; i++){
            for (int j = 0; j < N; j++){
                cin >> val[Hash(i, j)];
                if (i != 0){
                    dis[Hash(i, j)][Hash(i-1, j)] = val[Hash(i-1, j)];
                    dis[Hash(i-1, j)][Hash(i, j)] = val[Hash(i, j)];
                }
                if (j != 0){
                    dis[Hash(i, j)][Hash(i, j-1)] = val[Hash(i, j-1)];
                    dis[Hash(i, j-1)][Hash(i, j)] = val[Hash(i, j)];
                }
            }
        }
        //Floyd-Warshall
        for (int i = 0; i < N*N; i++)
            for (int j = 0; j < N*N; j++)
                for (int k = 0; k < N*N; k++)
                        dis[j][k] = min(dis[j][k],dis[j][i] + dis[i][k]);
        cin >> Q;
        while (Q--){
            minn = 0x7FFFFFFF;
            cin >>x>>y>>x2>>y2;
            x--,y--,x2--,y2--;
            for (int i = 0; i < N*N; i++)
                minn = min(minn, val[Hash(x, y)] + dis[Hash(x, y)][i] + dis[i][Hash(x2, y2)] - val[i]);
            cout << minn << "\n";
        }
    }
}
更新於 閱讀次數

用實際行動犒賞爆肝的我😀

Zrn Ye LinePay

LinePay