三个状态为有股票,没有股票的第一天,没有股票的第二天及以后
#include <iostream>
#include <cstring>
using namespace std;;
const int N=100010;
int f[N][3];
int a[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
//把不可达状态赋值为负无穷
memset(f,-0x3f,sizeof f);
for(int i=0;i<=n;i++)
{
//初始状态设置为0
f[0][2]=0;
}
for(int i=1;i<=n;i++)
{
//三个状态为有股票,没有股票的第一天,没有股票的第二天及以后
f[i][0]=max(f[i-1][0],f[i-1][2]-a[i]);
f[i][1]=f[i-1][0]+a[i];
f[i][2]=max(f[i-1][2],f[i-1][1]);
}
int res=0;
res=max(res,f[i][1]);
res=max(res,f[i][2]);
cout<<res;
return 0;
}
2023/11/28
状态机dp,算是玩明白了,干净又漂亮
// fij: 在前i天中买卖股票,当前状态为j的最大收益
总结:
1. 要注意状态入口,初始化所有状态为不合法,把入口的“可达”状态设置为0
2. 要弄清楚有几个状态,状态之间的转移关系
#include <iostream>
#include <cstring>
using namespace std;
const int N=100010;
// fij: 在前i天中买卖股票,当前状态为j的最大收益
int f[N][3];
int n;
int a[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
// 状态机入口
memset(f, -0x3f, sizeof(f));
// 最开始手里无股
for(int i=0;i<=n;i++)
{
f[i][0] = 0;
}
for(int i=1;i<=n;i++)
{
// 0: 当前手里无股
f[i][0] = max(f[i-1][0], f[i-1][2]);
// 1: 当前手里有股,可以卖
f[i][1] = max(f[i-1][1], f[i-1][0]-a[i]);
// 2: 冷冻期
f[i][2] = f[i-1][1]+a[i];
}
int res=0;
res = max(f[n][0], f[n][2]);
cout<<res;
return 0;
}