題目描述
shopee物流會有很多個中轉站。在選址的過程中,會選擇離使用者最近的地方建乙個物流中轉站。
假設給你乙個二維平面網格,每個格仔是房子則為1,或者是空地則為0。找到乙個空地修建乙個物流中轉站,使得這個物流中轉站到所有的房子的距離之和最小。 能修建,則返回最小的距離和。如果無法修建,則返回 -1。
若範圍限制在100*100以內的網格,如何計算出最小的距離和?
當平面網格非常大的情況下,如何避免不必要的計算?
解題思路:
本題資料並不大,暴力列舉完全可以解決問題,但是這樣寫顯然沒什麼技術含量。當資料過大,本題一般方法會超時,我們可以建立二維字首和來計算距離。
二維字首:
每一點的含義可以表述為:設dp[i][j]為右下頂點,以(1,1)為左上頂點所成的矩形中有多少個中轉站。很容易得狀態方程:dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + a[i][j];(在草稿紙上畫一下就可以直觀地看出來)
計算方式:
暴力列舉出頂點(1,1)到其他倉庫的距離和,每一次移動有兩種移動方式:
橫向向右移動和豎直向下移動。狀態方程分別為:
sum2 += 2 * dp[n][j - 1] - dp[n][n];
sum1 += 2 * dp[i - 1][n] - dp[n][n];
sum 表示該點到其他點的距離和。
**示例:
#include
using
namespace std;
int a[
101]
[101]=
, dp[
101]
[101]=
;int
main()
}int sum =0;
for(
int i =
1; i <= n; i++
)//使用狀態方程時需初始化第一行和第一列的值
dp[1]
[i]= sum;
} sum =0;
for(
int i =
1; i <= n; i++
) dp[i][1
]= sum;
}for
(int i =
2; i <= n; i++
)//計算dp[i][j]
for(
int j =
2; j <= n; j++
) dp[i]
[j]= dp[i]
[j -1]
+ dp[i -1]
[j]- dp[i -1]
[j -1]
+ a[i]
[j];
sum =0;
for(
int i =
1; i <= n; i++
)//計算出(1,1)到其他點的距離
for(
int j =
1; j <= n; j++
)int sum1,sum2;
sum1 = sum2 = sum;
for(
int i =
1; i <= n; i++)if
(!a[i][1
])sum =
min(sum1, sum)
,flag=1;
sum2 = sum1;
for(
int j =
2; j <= n; j++)}
if(flag)
cout << sum;
else
cout <<
"-1"
;return0;
}
物流中轉站
shopee物流會有很多個中轉站。在選址的過程中,會選擇離使用者最近的地方建乙個物流中轉站。假設給你乙個二維平面網格,每個格仔是房子則為1,或者是空地則為0。找到乙個空地修建乙個物流中轉站,使得這個物流中轉站到所有的房子的距離之和最小。能修建,則返回最小的距離和。如果無法修建,則返回 1。若範圍限制...
距離最短中轉站
建物流中轉站 牛客網 物流中轉站 題目描述 shopee物流會有很多個中轉站。在選址的過程中,會選擇離使用者最近的地方建乙個物流中轉站。假設給你乙個二維平面網格,每個格仔是房子則為1,或者是空地則為0。找到乙個空地修建乙個物流中轉站,使得這個物流中轉站到所有的房子的距離之和最小。能修建,則返回最小的...
牛客 OR175 物流中轉站 超詳細解答
題目描述 shopee物流會有很多個中轉站。在選址的過程中,會選擇離使用者最近的地方建乙個物流中轉站。假設給你乙個二維平面網格,每個格仔是房子則為1,或者是空地則為0。找到乙個空地修建乙個物流中轉站,使得這個物流中轉站到所有的房子的距離之和最小。能修建,則返回最小的距離和。如果無法修建,則返回 1。...