LeetCode 1066. 校园自行车分配 II(状态压缩DP)
文章目錄
- 1. 題目
- 2. 解題
- 2.1 回溯超時(shí)
- 2.2 狀態(tài)壓縮DP
1. 題目
在由 2D 網(wǎng)格表示的校園里有 n 位工人(worker)和 m 輛自行車(chē)(bike),n <= m。所有工人和自行車(chē)的位置都用網(wǎng)格上的 2D 坐標(biāo)表示。
我們?yōu)槊恳晃还と朔峙湟惠v專(zhuān)屬自行車(chē),使每個(gè)工人與其分配到的自行車(chē)之間的曼哈頓距離最小化。
p1 和 p2 之間的曼哈頓距離為 Manhattan(p1, p2) = |p1.x - p2.x| + |p1.y - p2.y|。
返回每個(gè)工人與分配到的自行車(chē)之間的曼哈頓距離的最小可能總和。
示例 1:
示例 2:
來(lái)源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/campus-bikes-ii
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
2. 解題
2.1 回溯超時(shí)
22 / 44 個(gè)通過(guò)測(cè)試用例
class Solution {int mindis = INT_MAX; public:int assignBikes(vector<vector<int>>& workers, vector<vector<int>>& bikes) {int nw = workers.size(), nb = bikes.size(), i, j;vector<vector<int>> dis(nw, vector<int>(nb));vector<bool> vis(nb, false);for(i = 0; i < nw; ++i)for(j = 0; j < nb; ++j)dis[i][j] = abs(workers[i][0]-bikes[j][0])+ abs(workers[i][1]-bikes[j][1]);dfs(workers, bikes, vis, dis, 0, 0);return mindis;}void dfs(vector<vector<int>>& workers, vector<vector<int>>& bikes,vector<bool> &vis, vector<vector<int>> &dis, int idx, int distance){if(idx == workers.size()){mindis = min(mindis, distance);return;}for(int i = 0; i < bikes.size(); ++i){if(vis[i]) continue;vis[i] = true;if(distance < mindis)dfs(workers, bikes, vis, dis, idx+1, distance+dis[idx][i]);vis[i] = false;}} };2.2 狀態(tài)壓縮DP
- 參考大力王的題解
類(lèi)似題目:LeetCode 5387. 每個(gè)人戴不同帽子的方案數(shù) hard
class Solution { public:int assignBikes(vector<vector<int>>& workers, vector<vector<int>>& bikes) {int m = workers.size(), n = bikes.size(), i, j;vector<vector<int>> dis(m, vector<int>(n));for(i = 0; i < m; ++i)for(j = 0; j < n; ++j)dis[i][j] = abs(workers[i][0]-bikes[j][0])+ abs(workers[i][1]-bikes[j][1]);int M = 1 << m, N = 1 << n;//每個(gè)人或者自行車(chē)都看成一個(gè)二進(jìn)制位,0還沒(méi)選,1選了vector<vector<int>> dp(M, vector<int>(N, 1000000));for(i = 0; i < m; ++i)for(j = 0; j < n; ++j)dp[1<<i][1<<j] = dis[i][j];for(i = 0; i < M; ++i)for(j = 0; j < N; ++j){int i_ = i, j_ = j;m = i&(-i);//二進(jìn)制數(shù)最后一個(gè)1代表的數(shù)值lowbitn = j&(-j);while(m > 0)//遍歷之前的人的狀態(tài){dp[i][j] = min(dp[i][j], dp[i-m][j-n]+dp[m][n]);//i-m表示少了?個(gè)1,少了?個(gè)人//j-n表示少了?輛車(chē)i_ -= m;//減掉一個(gè)人m = i_&(-i_);}m = i&(-i);//二進(jìn)制數(shù)最后一個(gè)1代表的數(shù)值lowbitn = j&(-j);while(n > 0)//遍歷之前的車(chē)子狀態(tài){dp[i][j] = min(dp[i][j], dp[i-m][j-n]+dp[m][n]);//i-m表示少了?個(gè)1,少了?個(gè)人//j-n表示少了?輛車(chē)j_ -= n;//減掉一輛車(chē)n = j_&(-j_);}}return *min_element(dp[M-1].begin(), dp[M-1].end());} };1376 ms 39 MB
我的CSDN博客地址 https://michael.blog.csdn.net/
長(zhǎng)按或掃碼關(guān)注我的公眾號(hào)(Michael阿明),一起加油、一起學(xué)習(xí)進(jìn)步!
總結(jié)
以上是生活随笔為你收集整理的LeetCode 1066. 校园自行车分配 II(状态压缩DP)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 02.改善深层神经网络:超参数调试、正则
- 下一篇: LeetCode 1738. 找出第 K