演算法分析與設計期中測試——最小和
阿新 • • 發佈:2018-11-03
從數列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 {
public:
int minSum(vector& A) {
}
};
例1:A = {2, 5, 2},答案為4.
例2:A = {2, 5, 4},答案為5.
注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.
比較容易往動態規劃的方向想,一開始用遞迴的方法做結果超時了,改成迴圈就可以了。不得不說動態規劃方法真的簡潔優雅效率又高,就是要考慮清楚邏輯的完備性。狀態轉移方程如下,意思就是前i個數字的最小和有兩種情況,一種包括第i個數字再加上前i-1個數字的最小和,另外一種包括第i-1個數字再加上前i-2個數字的最小和。要注意的是,比如說取了第i個數字不代表就不會取第i-1個數字,如2,5,2,1最優的情況是取2,2,1。
dp[i] = min(dp[i - 1 ] + A[i], dp[i - 2]+A[i-1]);
class Solution {
public:
int minSum(vector<int>& A) {
int *dp = new int[A.size()];
if (A.size() == 1) {
return A[0];
}
if (A.size() == 2) {
return min(A[0], A[1]);
}
if (A.size() == 3) {
min(A [0] + A[2], A[1]);
}
dp[0] = A[0];
dp[1] = min(A[0], A[1]);
dp[2] = min(A[0] + A[2], A[1]);
for (int i = 3; i < A.size(); i++) {
dp[i] = min(dp[i - 1] + A[i], dp[i - 2]+A[i-1]);
}
return dp[A.size() - 1];
}
};