今天做了一道购买股票的问题,每天有股价,可以买多次,卖多次,但是买之前必须清空手上的股票,问最大收益多少
转化为对a[]求i, j,使得max(a[j]-a[i]) st: 1<=i<j<=n
初看是个很简单的最值优化问题,但是也不是很好想,本来说先算a[] max min都算出来,看maxi>mini 就解决了,否则再另外处理,但是另外处理麻烦,
后来我转化为一个函数曲线,发现其实是找后面比前面大的最多的两个点出来,然后想到每一步都有一个increment,于是算出increment叠加最大的,也即最大字段和问题,这个问题是经典问题,
所以解法之一是讲问题转化为已有的经典问题,然后解决之,附上本吊的AC代码:
这里有一个小细节,就是最后如果max为负数,则返回0,因为可以买当日,卖当日,这个在当前转化为优化问题的时候处理了,到后面要回到这个特殊的case来,其实maxsum问题是可以处理最大和为负数的,我最早还写得是若为负数就定义为0.
本吊先写了一个 brute force方法,一个两重循环,操作次数n-1+....1= (n-1+1)(n-1)/2=n(n-1)/2, 是O(n^2)的复杂度,结果直接超时,所以用上述O(n)的算法就过了。
转化为对a[]求i, j,使得max(a[j]-a[i]) st: 1<=i<j<=n
初看是个很简单的最值优化问题,但是也不是很好想,本来说先算a[] max min都算出来,看maxi>mini 就解决了,否则再另外处理,但是另外处理麻烦,
后来我转化为一个函数曲线,发现其实是找后面比前面大的最多的两个点出来,然后想到每一步都有一个increment,于是算出increment叠加最大的,也即最大字段和问题,这个问题是经典问题,
所以解法之一是讲问题转化为已有的经典问题,然后解决之,附上本吊的AC代码:
int maxProfit_MaxSum(vector<int> &prices)
{
if(prices.size()<=1)return 0;
int max=prices.at(1)-prices.at(0),b=0,increment;
for(int i=1;i<prices.size();i++)
{
increment=prices.at(i)-prices.at(i-1);
if(b>=0)
b+=increment;
else
b=increment;
if(max<b)
max=b;
}
if(max<0)return 0;
return max;
}
这里有一个小细节,就是最后如果max为负数,则返回0,因为可以买当日,卖当日,这个在当前转化为优化问题的时候处理了,到后面要回到这个特殊的case来,其实maxsum问题是可以处理最大和为负数的,我最早还写得是若为负数就定义为0.
本吊先写了一个 brute force方法,一个两重循环,操作次数n-1+....1= (n-1+1)(n-1)/2=n(n-1)/2, 是O(n^2)的复杂度,结果直接超时,所以用上述O(n)的算法就过了。