题目描述
给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例1
输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例2
输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
动态规划算法
开辟一个长度与prices数组相同的二维dp数组,dp[i][0]表示当日持有股票所累积的最大利润,dp[i][1]表示当日持有股票的最大利润.设prices 长度为n,易知当最后一天不持有股票时,才能获得最大利润。因此只需求出dp[n-1][1]即可。
状态转移方程为:
i=0:
i>0:
C++代码
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
int maxProfit(vector<int>& prices)
{
int** dp = new int* [prices.size()];
for (int i = 0; i < prices.size(); i++)
{
dp[i] = new int[2];
dp[i][0] = 0; dp[i][1] = 0;
}
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < prices.size(); i++)
{
dp[i][0] = dp[i - 1][0] > dp[i - 1][1] - prices[i] ? dp[i - 1][0] : dp[i - 1][1] - prices[i];
dp[i][1] = dp[i - 1][0] + prices[i] > dp[i - 1][1] ? dp[i - 1][0] + prices[i] : dp[i - 1][1];
}
return dp[prices.size() - 1][1];
}
};
int main() {
int n=0;
vector<int>prices;
while (cin >> n)
{
if (n == 0)break;
prices.push_back(n);
}
Solution DP;
int result = DP.maxProfit(prices);
cout << result << endl;
}
python代码
cin=input()
temp=cin.split(' ')
dp=[]
for i in range(len(temp)):
dp.append([0,0])
dp[0][0]=-eval(temp[0])
dp[0][1]=0
for i in range(1,len(temp)):
dp[i][0]=max(dp[i-1][0],dp[i-1][1]-eval(temp[i]))
dp[i][1]=max(dp[i-1][0]+eval(temp[i]),dp[i-1][1])
print(dp[i][0],end=' ')
print(dp[i][1])
print(dp[len(temp)-1][1])
贪心算法
当区间的值连续增大时,右端点的值减去左端点的值大于子区间的右端点值减去左端点值之和;
当区间的值不连续增大时,右端点的值减去左端点的值小于连续增大的子区间的右端点值减去左端点值之和。
因此,只需求出所有连续增大的区间的右端点值减去左端点值之和。
C++代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
int maxProfit(vector<int>& prices) {
prices.push_back(-1);
int* profit = new int[prices.size()];
int top = 0;
int i = 0, j = 1;
int sum = 0;
while (j < prices.size())
{
if (prices[j - 1] < prices[j])
{
j++;
}
else
{
if (j - 2 < 0)
{
i = j;
j++;
continue;
}
if (prices[j - 1] > prices[j - 2])
{
sum += prices[j - 1] - prices[i];
i = j;
j += 1;
}
else
{
i = j;
j += 1;
}
}
}
return sum;
}
};
int main()
{
Solution P;
vector<int>prices;
int n = 0;
while (cin >> n)
{
if (n == 0)break;
prices.push_back(n);
}
cout<<P.maxProfit(prices);
}