運輸問題
初讀題目,可能有點搞不懂。題目要求:二當一(兩件的**算一件),並且給出了這個**是如何計算的。題目的關鍵點在:如此反覆。直到只收一件商品的錢。 分析到這,是否感覺有點類似哈夫曼編碼以及洛谷中的另一道貪心習題-合併果子?
按照這個思路,寫出如下的**:
#include
#include
using
namespace std;
bool
cmp(
int a,
int b)
intmain()
ars[j-1]
= t;
} cout << ars[n-1]
;return0;
}
提交後發現,思路正確。但是不禁有兩個疑問:a.為什麼採取上述策略可以有效解決問題呢?b.上述**的時間複雜度顯然是o(n^2),耗時的操作主要浪費在為新值尋找合適位置上了。是否存在有效的解決方案降低時間複雜度呢?看了很多博文,大佬們用的都是優先佇列,不妨通過此類題目學習一下優先順序佇列。按照上述兩個疑問,本篇博文一下將分別分析。
題目要求運費最少,則最優解為運費最少的情況。分析運費的計算情況,如何讓運費最少?我們不妨將上述新運費計算方式當作一種打折活動,買東西時,我們自然希望貴重的物品的折扣越大越好,或者打的折扣次數盡量多。回到本題,若每次最貴重的物品參與的/k次數越多,最終的費用也不久最少嗎?相比選擇便宜的物品,打相同次數的折扣自然要比貴重物品少很多。因此問題不難得證。
其使用方法同普通佇列沒有什麼區別,先看下其一般使用方法:
#include
using
namespace std;
intmain()
cout <<
"priority_queue:"
<< endl;
for(
int i =
0; i <
10; i++
) cout <<
"\nqueue:"
<< endl;
for(
int i =
0; i <
10; i++
)return0;
}
通佇列基本沒有什麼區別,不同的是,其是按序排列的。通過上述實踐,也可以發現:優先順序佇列預設按最大值優先的順序。
倘若我們想改變優先順序順序,該如何實現?c++提供了自帶的庫函式,當然我們也可以自定義。先看下自帶的庫函式操作:
#include
using
namespace std;
intmain()
cout <<
"greater:"
<< endl;
for(
int i =
0; i <
10; i++
) cout <<
"\nque_greater_equal:"
<< endl;
for(
int i =
0; i <
10; i++
)return0;
}
自定義比較操作:
#include
using
namespace std;
struct cmp1};
struct cmp2};
intmain()
cout <<
"cmp1:\n"
;for
(int i =
0; i <
10; i++
) cout <<
"\ncmp2:\n"
;for
(int i =
0; i <
10; i++
)return0;
}
將上述題目用優先順序佇列重寫一下:
#include
#include
#include
using
namespace std;
intmain()
for(
int i =
0, j; i < n-
1; i++
) cout << que.
top();
return0;
}
優先順序佇列(下)
洛谷 P2680 運輸計畫
公元 2044 年,人類進入了宇宙紀元。l 國有 n 個星球,還有 n 1 條雙向航道,每條航道建立在兩個星球之間,這 n 1 條航道連通了 l 國的所有星球。小 p 掌管一家物流公司,該公司有很多個運輸計畫,每個運輸計畫形如 有一艘物 流飛船需要從 ui 號星球沿最快的宇航路徑飛行到 vi 號星球...
洛谷P1084 運輸計畫
題目 題目要求使一條邊邊權為0時,m條路徑的長度最大值的最小值。考慮二分此長度最大值 首先需要用lca求出樹上兩點間的路徑長度。然後取所有比mid大的路徑的交集,判斷有哪些邊在這些路徑上都有出現,然後這些邊裡面取最大值當做蟲洞,如果還是不行說明此mid不行。判斷邊可以用把邊化為點,然後樹上差分判斷每...
洛谷 P4015 運輸問題 題解
題目鏈結 w ww 公司有 m mm 個倉庫和 n nn 個零售商店。第 i ii 個倉庫有 a ia i ai 個單位的貨物 第 j jj 個零售商店需要 b jb j bj 個單位的貨物。貨物供需平衡.從第 i ii 個倉庫運送每單位貨物到第 j jj 個零售商店的費用為 cij c ci j ...