class Solution {
public:
Solution(){}
int maxProfit(int K, vector<int> &prices) {
vector<int> lowVec;
vector<int > highVec;
if(prices.size() <=1){
return 0;
}
prices.erase(std::unique(prices.begin(),prices.end()),prices.end());
if(prices.size() <=1){
return 0;
}
lowVec.reserve(prices.size()/2);
highVec.reserve(prices.size()/2);
if(prices[0]<prices[1]){
lowVec.push_back(prices[0]);
}
for(int i=1;i<prices.size()-1;i++){
int low;
int cur = prices[i];
if(cur<prices[i+1] && cur<prices[i-1]){
lowVec.push_back(cur);
}
if(cur>prices[i-1]&&cur>prices[i+1]){
highVec.push_back(cur);
}
}
if(prices[prices.size()-2]<prices[prices.size()-1]){
highVec.push_back(prices.back());
}
int N = lowVec.size();
if(K>=N){
int sum=0;
for(int i=0;i<N;i++){
sum += highVec[i]-lowVec[i];
}
return sum;
}
vector<vector<int> > opt ;
opt.resize(K+1);
for(int i=0;i<K+1;i++)
{
opt[i].resize(N);
}
vector<int>diff;
diff.reserve(lowVec.size());
int sum=0;
for(int i=0;i<N;i++){
sum += (highVec[i]-lowVec[i]);
diff.push_back(sum);
}
for(int k=1;k<=K;k++)
{
for(int i=0;i<k;i++){
opt[k][i]= diff[i];
}
}
for(int i=0;i<N;i++){
opt[0][i]=0;
}
for(int k=1;k<=K;k++)
{
for(int i=k;i<N;i++)
{
opt[k][i] = max(opt[k][i-1],opt[k-1][i-1]+highVec[i]-lowVec[i]);
opt[k][i] = max(opt[k][i],highVec[i]-lowVec[0]);
for(int t=i-1;t>=k-1 && t>0;t--){
int highDiff = highVec[i]-highVec[t];
int lowDiff = lowVec[i]-lowVec[t];
if(highDiff>0 && lowDiff>0){
opt[k][i]=max(opt[k][i],opt[k-1][t-1]+highVec[i]-lowVec[t]) ;
}
else break;
}
}
}
return opt[K][N-1];
}
};
188 | Best Time to Buy and Sell Stock IV |
说明:有个地方不同其他程序。即先删除一些无用的状态(即非波峰波谷,这些状态属于中间态,因此,肯定赚钱不了的),比如 {2,3,4,3,2}其中的3就是无用状态。对于最后一个元素,如果不是涨价,也是无用,第一个元素,如果不比第二个元素小,也是无效状态
动态规划的主要公式:
opt[k][i]=max(opt[k][i],opt[k-1][t-1]+highVec[i]-lowVec[t])
即,如果选择当前第i个股价卖出,那么,需要选取第t个股价买入(0<=t<i),同时在t前面选择k-1个操作即opt[k-1][t-1]