股票买卖 IV
题目链接:acwing1057. 股票买卖 IV
问题描述:
分析:
首先画出状态机模型,有两种状态:手中有货和手中无货,
手中有货可以继续保持,或者卖掉
手中有货可以继续保持,或者买入
状态表示:用
f[i][j][0]表示当前第i天,第j(<=k)次交易,此时手中无货的最大价值
f[i][j][1]表示当前第i天,第j(<=k)次交易,此时手中有货的最大价值
状态转移:
由下图可知,
f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]+g[i]);//这是一次交易,交易数量没变
f[i][j][1]=max(f[i-1][j-1][0]-g[i],f[i-1][j][1]);//买入算新的一次交易
初始化:
因为有交易次数限制,所以在第一次交易时不能卖出,可以令f[i][0][1]=-inf
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+10,K=110;
int f[N][K][2];
int g[N];
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++) scanf("%d",&g[i]);
memset(f,-0x3f,sizeof f);
for(int i=0;i<=n;i++) f[i][0][0]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++){
f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]+g[i]);
f[i][j][1]=max(f[i-1][j][1],f[i-1][j-1][0]-g[i]);
}
int t=-1;
for(int i=0;i<=k;i++) t=max(t,f[n][i][0]);
cout<<t;
return 0;
}
股票买卖 V
题目链接:acwing1057. 股票买卖 V
问题描述:
分析:
这道题没有交易次数的限制,但是有了冷却时间,我们需要添加一维来表示冷却时间
状态表示:
f[i][0]:表示当前为第i天,且手中有货的最大价值
f[i][1]:表示当前为第i天,且手中无货一天的最大价值
f[i][2]:表示当前为第i天,且手中无货>=两天的最大价值
状态转移:
f[i][0]=max(f[i-1][0],f[i-1][2]-g[i]);
f[i][1]=f[i-1][0]+g[i];
f[i][2]=max(f[i-1][2],f[i-1][1]);
初始化:由于第一天是可以买入(无货时间>=2)的,所以
f[0][0][1]=f[0][0]=-inf
f[0][0][2]=0
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+10;
int f[N][3];
int main(){
int n;
cin>>n;
f[0][1]=f[0][0]=-0x3f3f3f3f;
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
f[i][0]=max(f[i-1][0],f[i-1][2]-x);
f[i][1]=f[i-1][0]+x;
f[i][2]=max(f[i-1][1],f[i-1][2]);
}
cout<<max(f[n][1],f[n][2])<<endl;
return 0;
}