最小和
總結一道需要花點時間的題,題目本身不難理解。
總結一道動態規劃問題。
在圖論中,拓撲序(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:注意:你只需要提交solution類的**,你在本地可以編寫main函式測試程式,但不需要提交main函式的**. 注意不要修改類和函式的名稱.n = 3,edges = ,函式應返回或者.
例2:
n = 4,edges = ,函式應返回.
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.注意:你只需要提交solution類的**,你在本地可以編寫main函式測試程式,但不需要提交main函式的**. 注意不要修改類和函式的名稱.例2:a = ,答案為5.
考試的時候我其實沒有理解這道題,以為相鄰兩個數必選乙個數且這個數可以被選擇多遍。在例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,...