演算法分析與設計 第十六周 期中小結(中)

2021-08-13 23:38:30 字數 2863 閱讀 5812

最小和

總結一道需要花點時間的題,題目本身不難理解。

總結一道動態規劃問題。

在圖論中,拓撲序(topological sorting)是乙個有向無環圖(dag, directed acyclic graph)的所有頂點的線性序列. 且該序列必須滿足下面兩個條件:

每個頂點出現且只出現一次.

若存在一條從頂點 a 到頂點 b 的路徑,那麼在序列中頂點 a 出現在頂點 b 的前面.

對於乙個含有n個節點的有向無環圖(節點編號0到n-1),輸出它的乙個拓撲序.

圖的節點數和邊數均不多於100000,保證輸入的圖是乙個無環圖.

請為下面的solution類實現解決上述問題的topologicalsort函式,函式引數中n為圖的節點數,edges是邊集,edges[i]表示第i條邊從edges[i].first指向edges[i].second. 函式返回值為有向圖的乙個拓撲序. 有向圖有多個拓撲序時,輸出任意乙個即可.

class solution 

};

例1:

n = 3,edges = ,函式應返回或者.

例2:

n = 4,edges = ,函式應返回.

注意:你只需要提交solution類的**,你在本地可以編寫main函式測試程式,但不需要提交main函式的**. 注意不要修改類和函式的名稱.

dfs,並記錄結點的post值

class solution 

dfs(edge[i], n, edgetable, enter, post);

if (post[nowpoint] >= post[edge[i]]) post[nowpoint] = post[edge[i]] - 1;

}// 已經遍歷完畢,退出,如果是葉節點,修改post

if (post[nowpoint] == n) post[nowpoint] = n - 1;

}vector

topologicalsort(int n, vector

int, int>>& edges)

// 處理邊成線性表

vector

edgetable[n];

for (int i = 0; i < edges.size(); i++)

edgetable[edges[i].first].push_back(edges[i].second);

// 遞迴

for (int i = 0; i < n; i++)

dfs(i, n, edgetable, enter, post);

// 對順序進行排序

vector

int, int>> sortarr;

for (int i = 0; i < n; i++)

sortarr.push_back(pair(post[i], i));

sort(sortarr.begin(), sortarr.end());

vector

returnarr;

for (int i = 0; i < n; i++)

returnarr.push_back(sortarr[i].second);

return returnarr;

}};

o(n+e)

從數列a[0], a[1], a[2], …, a[n-1]中選若干個數,要求對於每個i(0<= i < n-1),a[i]和a[i+1]至少選乙個數,求能選出的最小和.

1 <= n <= 100000, 1 <= a[i] <= 1000

請為下面的solution類實現解決上述問題的函式minsum,函式引數a是給出的數列,返回值為所求的最小和.

class solution 

};

例1:a = ,答案為4.

例2:a = ,答案為5.

注意:你只需要提交solution類的**,你在本地可以編寫main函式測試程式,但不需要提交main函式的**. 注意不要修改類和函式的名稱.

考試的時候我其實沒有理解這道題,以為相鄰兩個數必選乙個數且這個數可以被選擇多遍。在例2:a =中,我一直以為2和5中必選乙個,5和4中必選乙個,所以認為答案應該是6,而忽略了2和5中選擇5,因此5和4中就不必再次選擇的情況。

至今不明白為什麼會有如此奇怪的想法,大概是考試的時候人比較緊張,會做出一些奇怪的判斷。┑( ̄д  ̄)┍

所以這道題無法使用貪心演算法解題,反而可以分解為公共子問題,核心思想其實是動態規劃。

其實在正確理解題意之後,我就清醒了。但是我仍然覺得這是一道中階動態規劃題。寫出狀態轉移式還是花費了一番周折。

寫出狀態轉移式之後就清晰了。

狀態轉移式:

// f[0][i]表示第i位數沒被選中時前i位的最小和

// f[1][i]表示第i位數被選中時前i位的最小和

// a是給出的數列

init:

f[0][0] = 0

f[1][0] = a[0]

-------------

f[0][i] = f[1][i-1] // 若不選第i個,則根據「相鄰兩個數至少選其一」的規則,必須選擇第i-1個

f[1][i] = a[i] + min

------------

result:

min // 無法得知最後乙個到底有沒有被選中,所以取總和小的

class solution 

return min(f[0][n-1], f[1][n-1]);

}};

o(n)

演算法分析與設計第十六周

分析 每次移除乙個數,要盡可能使前面的數最小,因為前面的數的權值最大。而刪除乙個數,會導致後面緊接著的乙個數代替刪除的數的位置。所以在一次移除操作中,從前往後檢查,一旦發現某個數後繼的數更小,則刪除此數。複雜度為o k n 可以採用遞迴的方法實現。然而遞迴 leetcode顯示記憶體超出,應該是棧溢...

演算法設計與應用基礎 第十六周(1)

最大流最小割的c 實現 演算法說明 通過上課老師的講解結合自己的看書理解和上網查詢資料,用c 實現了網路流中最大流的求解 ek 演算法,其中每次搜尋是否有增廣路用bfs搜尋以提高效率,維護兩個陣列pre和flow 其作用在 中有注釋 每次找到一條增廣路後修改殘留網路的流量值,如下 include i...

演算法作業 27 2017 6 8第十六周

120.given a find the minimum path sum from top to bottom.each step you may move to adjac numbers on the row below.for example,given the following 2 3,...