题目
1058. 股票买卖 V
法一 三个状态
- 除了有货、无货两个状态,增设一个冷冻期状态
f[i][0]
表示无货,f[i][1]
表示有货,f[i][2]
表示处于冷冻期
f[0][1]
为非法状态,初始值为无穷小
![](https://img2022.cnblogs.com/blog/1143334/202206/1143334-20220604111621467-1798088585.jpg)
代码1
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 100005;
const int INF = 0x3f3f3f3f;
int w[maxn], f[maxn][3];
int main() {
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n;
cin >> n;
for(int i = 1; i <= n; ++i) cin >> w[i];
memset(f, 0, sizeof f);
f[0][1] = -INF;
for(int i = 1; i <= n; ++i) {
f[i][0] = max(f[i - 1][0], f[i - 1][1] + w[i]);
f[i][1] = max(f[i - 1][1], f[i - 1][2] - w[i]);
f[i][2] = max(f[i - 1][2], f[i - 1][0]);
}
cout << max(f[n][0], f[n][2]) << endl;
return 0;
}
法二 两个状态
- 仅设置两个状态,有货和无货
- 有货的状态可有昨天有货状态转移或者前天无货状态转移(避开冷冻期)
f[0][1]
为非法状态,设置初值为无穷小,f[1][1]
根据转移方程,没有f[-1][0]
的状态,且f[0][1]
为非法状态,实际考虑,第一天必须买入,故初始值为-w[1]
代码2
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 100005;
const int INF = 0x3f3f3f3f;
int w[maxn], f[maxn][2];
int main() {
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n;
cin >> n;
for(int i = 1; i <= n; ++i) cin >> w[i];
memset(f, 0, sizeof f);
f[0][1] = -INF;
f[1][0] = 0;
f[1][1] = -w[1];
for(int i = 2; i <= n; ++i) {
f[i][0] = max(f[i - 1][0], f[i - 1][1] + w[i]);
f[i][1] = max(f[i - 1][1], f[i - 2][0] - w[i]);
}
cout << f[n][0] << endl;
return 0;
}