AcWing 1055. (贪心/DP)股票买卖 II
原题链接
简单
作者:
Avetre
,
2025-04-04 21:59:39
· 湖北
,
所有人可见
,
阅读 3
方法一:贪心
思路:
任何一个跨度大于1天的交易
都可以等价
为若干个跨度等于1天的交易
,即任意一种买卖方式可拆分成跨度均为1天的买卖。(如1,2,3,4,5,第一天买入在第5天卖出,为最大盈利4,可以拆分成1买2卖+2买3卖+3买4卖+4买5卖,简而言之就是遇增则买
)
原理:
1.c - a = (b - a) + (c - b)
:任何一个跨度天数大于1的交易(a价天买,c价天卖),等价于拆分成的若干个(c-a个)连续的单天跨度交易(即与他们中间这些天的价格b无关,即使跌价,b较a跌得越狠,c较b升得就越快,两者效果抵消
)
2.一个区间天数(左端点时刻买入,右端点时刻卖出)内盈利最大时,对应的集合{(at,at+1),(at+1,at+2),…}中每一个区间均为正值(存在负值就该剔除),即每个单天跨度都是递增的
,故要想在整个时间线上盈利最大
,即只在所有递增的子区间进行交易
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
int price[N];
int main()
{
cin >> n;
for(int i = 0;i < n;i ++) cin >> price[i];
int res = 0;
for(int i = 0;i + 1 < n;i ++)
{
int dt = price[i+1] - price[i];
if(dt > 0)
res += dt;
}
cout << res << endl;
return 0;
}
方法二:DP
思路:

代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int N;
cin >> N;
vector<int> price(N);
for (int i = 0; i < N; i++)
cin >> price[i];
vector<vector<int>> dp(N, vector<int>(2, 0));
dp[0][0] = 0;
dp[0][1] = -price[0];
for (int i = 1; i < N; i ++) {
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + price[i]);
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - price[i]);
}
cout << dp[N-1][0] << endl;
return 0;
}