状态机dp入门-股票买卖 IV、V、VI

股票买卖-IV

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例1

3 2
2 4 1

输出样例1

2

输入样例2

6 2
3 2 6 5 0 3

输出样例2

7

样例说明

扫描二维码关注公众号,回复: 13224412 查看本文章

在这里插入图片描述


III 版本的一点点加强,仅需要将上一题的 k 范围扩大即可。

参考代码

#include <bits/stdc++.h>
using namespace std;

const int N=1e5+10;
int a[N];
int f[N][110][2];

int main(){
    
    
    int n,k;
    cin>>n>>k;
    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] = 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]+a[i]);
            f[i][j][1]=max(f[i-1][j-1][0]-a[i],f[i-1][j][1]);
        }
    }
    int res=0;
    for(int i=0;i<=k;i++){
    
    
        res=max(res,f[n][i][0]);
    }
    cout<<res<<endl;
    
    return 0;
}

股票买卖-V

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例

5
1 2 3 0 2

输出样例

3

样例说明

在这里插入图片描述


本题与上一版本 IV 的区别在于:

① 没有操作次数的限制

② 在卖出股票后的第一天不能够买入

由于本题不再有操作次数限制,因此可以省略之前第二维关于次数的状态表示,如何对【冷冻期】进行表示及相关的状态转换才是问题。

由于冷冻期的存在,因为先前的状态可以由 1 转化为 0 (即持有股票状态下可直接卖出),但不能再直接由 0 转化为 1 (即此时应当进入冷冻期,不可买入股票交易)。显然,对于手中没有股票时可分为两种情况:

① 处于冷冻期中,第二天不可购买

② 已过冷冻期,第二天可以购买

为了标识这两种情况,可以考虑添加一个 2 状态用于区分。其中,卖出后状态将由 1 转为 0,并将进入冷冻期,即 0 状态将在下一天强制转为 2 状态 。而 2 状态则表示冷冻期已经结束(不论已经结束了多少天),可以进行买入即由 2 转为 1 。注意不能够将 2 状态转化为 0 状态。

参考代码

#include <bits/stdc++.h>
using namespace std;

const int N=1e5+10,inf=0x3f3f3f3f;
int a[N];
int f[N][3];

int main(){
    
    
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	f[0][1]=f[0][0]=-inf;
	for(int i=1;i<=n;i++){
    
    
		f[i][0]=f[i-1][1]+a[i];//由于该状态只能由 f[i-1][1] 转化而来 因此不需要max
		f[i][1]=max(f[i-1][1],f[i-1][2]-a[i]);
		f[i][2]=max(f[i-1][2],f[i-1][0]);
	}
	cout<<max(f[n][0],f[n][2]);
	
	return 0;
}

股票买卖-VI

题目描述

在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

输入样例

6 2
1 3 2 8 4 9

输出样例

8

样例说明

在这里插入图片描述


返璞归真的一题,注意买入时同时需要减去手续费即可。

参考代码

#include <bits/stdc++.h>
using namespace std;

const int N=1e5+10,inf=0x3f3f3f3f;
int a[N];
int f[N][2];

int main(){
    
    
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	f[0][1]=-inf;
	for(int i=1;i<=n;i++){
    
    
		f[i][0]=max(f[i-1][0],f[i-1][1]+a[i]);
		f[i][1]=max(f[i-1][1],f[i-1][0]-a[i]-m); 
	}
	
	cout<<f[n][0]<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/laysan/article/details/121161095
今日推荐