uva 11997
題意:給你乙個數k,並且給你k組數,每組k個數,現在在每組中任取乙個數,然後相加可以得到乙個和,這樣的和共有k^k個,要求輸出所有可能的和值中最小的k個。
思路:問題1:如果只有a,b,c三個大小為k的陣列,我們如何求"和"能獲得最小的前k個和呢?
我們只需要將a和b陣列求出前k小的和(第k+1小到之後的所有和值我們都不用管,因為後面壓根用到這些值),然後用這個和陣列去同樣與c陣列求出前k小的和即可。如果有k個這樣的陣列,我們依然用a1與a2求前k小的和,然後用和陣列
與a3再求和,然後用結果再繼續同樣與a4求和,與a5求和...等即可。
問題2:a和b兩個陣列求前k小的和,如何計算能快速得到解呢?
窮舉法要k^2的複雜度.這裡我們用優先佇列來解.因為原本有k^2個可能的和結果。
假設a與b中的數已經排好了序(從小到大),那麼前k小的數肯定從下面k個佇列中出來(我們等同於將k^2個和分成了k個佇列,且每個佇列中的元素都是從小到大排列
):佇列1: a[1]+b[1] , a[1]+b[2] , … , a[1]+b[k]
佇列2: a[2]+b[1] , a[2]+b[2] , … , a[2]+b[k]
佇列3: a[3]+b[1] , a[3]+b[2] , … , a[3]+b[k]
佇列4: a[4]+b[1] , a[4]+b[2] , … , a[4]+b[k]
...佇列4: a[k]+b[1] , a[k]+b[2] , … , a[k]+b[k]
且每個佇列中隊首元素肯定是當前最小的候選和之一.所以我們每次從上述k個佇列中的k個隊首元素裡找出最小的那個作為乙個前k小的和(每次操作複雜度為logk),連續k次操作可以得到所有前k小的和。
(注意:程式實現只用了乙個優先佇列priority_queue,此佇列中儲存了上述k個佇列的k個對首元素
)所以我們只需要k^logk複雜度即可求出2個陣列組合的前k小數.
綜上所述,我們只需要一次構建兩個陣列的前k小數即可求得最小的前k小數了.
#includeusing namespace std;
typedef long long ll;
const int maxn=800;
int a[maxn],b[maxn],k;
struct node
; bool operator <(const node& rhs)const ;
};//void cal(int &a,int &b,int &c,int k)
void cal(int *a,int *b,int *c,int k)
{ priority_queueq;
int i;
for(i=0;i
資料結構 STL
棧 先入後出 filo 的一種資料結構。常見操作 模擬火車調頭,進製轉換,表示式求值,單調棧 陣列形式 理解 const int num 1e6 10 定義棧的大小,可自由改變 int stac num 乙個整型棧 int top 棧頂指標 int main top 1 設定棧頂指標為 1 stac...
資料結構 stl
1022 心中mmp,很簡單的一道題目,做了兩個小時,改錯乙個半小時,最後錯出在了while的判斷條件上,有什麼區別麼。題意 給出該數字序列的進棧順序,並給出要求的出棧順序,要你判斷是否能按照這個順序出棧。思路 我們只要用兩個指標i和j,指向當前需要處理的入棧和出棧的那個字元即可。先看如果我們把棧s...
STL資料結構
include pritorityq 大根堆 priority queue,greater q 小根堆 structno v值xiao的優先 queueq include vectorvec vec.push back 加入,從0開始 vec.size vec.pop back 刪除末尾 vec.c...