1.基礎知識
貪心算法是針對要解決的問題,先做出選擇,再解決剩下的子問題。將子問題的最優解和我們所作的貪心選擇聯合起來,就可以得出原問題的最優解,即全局最優解可以通過局部最優(貪心)選擇來達到。
貪心與動規的區別:
在動態規劃中,每一步做出的選擇都依賴於子問題的解,因此解動態規劃一般是自底向上的。
而貪心算法中,我們所做的當前選擇可能依賴於已經做出的所有選擇,但不依賴於子問題的解,因此通常是自頂向下的。
2.應用連續子數組的最大和
題目:輸入一個整型數組, 數組裏有正數也有負數. 數組中一個或連續的多個整數組成一個子數組. 求所有子數組的和的最大值. 要求時間複雜度爲
貪心法:
依次遍歷數組,若當前和爲正數,則加上後面數字可能會組成連續子數組的最大和;若當前和爲負數,則將其置0.
#include<iostream>
#include<vector>
using namespace std;
int getMaxSum(const vector<int> &v);
int main() {
vector<int> v1={-2, 5, 3, -6, 4, -8, 6};
vector<int> v2={-2, -5, -3, -6, -4, -8, -6};
vector<int> v3={2, 5, 3, 6, 4, 8, 6};
vector<int> v4;
cout << getMaxSum(v1) << endl;
cout << getMaxSum(v2) << endl;
cout << getMaxSum(v3) << endl;
cout << getMaxSum(v4) << endl;
return 0;
}
int getMaxSum(const vector<int> &v) {
int len=v.size();
int tempSum=0;
int maxSum=0;
for(int i=0; i<len; i++) {
tempSum += v.at(i);
if(tempSum<0) tempSum=0;
if(maxSum<tempSum) maxSum=tempSum;
}
return maxSum;
}
動態規劃法:
用函數
這個公式的意義:當以第i-1個數字結尾的子數組中所有數字的和小於0時,如果把這個負數與第i個數累加,得到的結果比第i個數字本身還要小,所以這種情況下以第i個數字結尾的子數組就是第i個數字本身。如果以第i-1個數字結尾的子數組中所有數字的和大於0,與第i個數字累加就得到以第i個數字結尾的子數組中所有數字的和。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int getMaxSum(const vector<int> &v);
int main() {
vector<int> v1={-2, 5, 3, -6, 4, -8, 6};
vector<int> v2={-2, -5, -3, -6, -4, -8, -6};
vector<int> v3={2, 5, 3, 6, 4, 8, 6};
vector<int> v4;
cout << getMaxSum(v1) << endl;
cout << getMaxSum(v2) << endl;
cout << getMaxSum(v3) << endl;
cout << getMaxSum(v4) << endl;
return 0;
}
int getMaxSum(const vector<int> &v) {
int len=v.size();
if(len <= 0) return 0;
vector<int> f(len);
f.at(0)=v.at(0);
for(int i=1; i<len; i++) {
if(f.at(i-1)<=0) f.at(i)=v.at(i);
else f.at(i)=f.at(i-1)+v.at(i);
}
return *max_element(f.begin(), f.end() );
}