DP31 买卖股票的最好时机(二)、(三)、(四)

买卖股票的最好时机(二)

描述

假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益

1. 你可以多次买卖该只股票,但是再次购买前必须卖出之前的股票

2. 如果不能获取收益,请返回0

3. 假设买入卖出均无手续费

要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

输入描述:

第一行输入一个正整数 n ,表示数组 prices 的长度

第二行输入 n 个正整数,表示数组中prices的值

输出描述:

输出最大收益

示例1

输入:

7
8 9 2 5 4 7 1

复制输出:

7

复制说明:

在第1天(股票价格=8)买入,第2天(股票价格=9)卖出,获利9-8=1
在第3天(股票价格=2)买入,第4天(股票价格=5)卖出,获利5-2=3
在第5天(股票价格=4)买入,第6天(股票价格=7)卖出,获利7-4=3
总获利1+3+3=7,返回7     
 

示例2

输入:

5
5 4 3 2 1

复制输出:

0

复制说明:

由于每天股票都在跌,因此不进行任何交易最优。最大收益为0。          

示例3

输入:

5
1 2 3 4 5

复制输出:

4

复制说明:

第一天买进,最后一天卖出最优。中间的当天买进当天卖出不影响最终结果。最大收益为4。      
#include<stdio.h>
#include<algorithm>
using namespace std;
int prices[100005];
int dp[100005][3];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&prices[i]);
    }
    int ans=0;
    int pre=prices[1];
    for(int i=2;i<=n;i++)
    {
       int current=prices[i];
        if(current>pre)
        {
            ans+=current-pre;
           
        }
         pre=current;
    }
    printf("%d\n",ans);
    return 0;
}

DP32 买卖股票的最好时机(三)

描述

假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你最多可以对该股票有两笔交易操作,一笔交易代表着一次买入与一次卖出,但是再次购买前必须卖出之前的股票
2. 如果不能获取收益,请返回0
3. 假设买入卖出均无手续费

要求: 空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)

输入描述:

第一行输入一个正整数 n ,表示数组 prices 的长度

第一行输入 n 个正整数,表示数组 prices 的所有元素的值 

输出描述:

输出最大收益

示例1

输入:

6
8 9 3 5 1 3

复制输出:

4

复制说明:

第三天(股票价格=3)买进,第四天(股票价格=5)卖出,收益为2
第五天(股票价格=1)买进,第六天(股票价格=3)卖出,收益为2
总收益为4。             
 

示例2

输入:

4
9 8 4 1

复制输出:

0

复制

示例3

输入:

5
1 2 8 3 8

复制输出:

12

复制说明:

第一笔股票交易在第一天买进,第三天卖出;第二笔股票交易在第四天买进,第五天卖出;总收益为12。
因最多只可以同时持有一只股票,所以不能在第一天进行第一笔股票交易的买进操作,又在第二天进行第二笔股票交易的买进操作(此时第一笔股票交易还没卖出),最后两笔股票交易同时在第三天卖出,也即以上操作不满足题目要求。    

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int prices[100005];
int dp[100005][5];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&prices[i]);
    }
    //dp[i][0]表示到第i天为止没有买卖过股票的最大收益
    //dp[i][1]表示到第i天为止买过一次股票还没有卖出的最大收益
    //dp[i][2]表示到第i为止买卖过一次股票的最大收益
    //dp[i][3]表示到第i天为止买了两次卖出一只的最大收益
    //dp[i][4]表示到第i天为止买卖了两次股票的最大收益
    for(int i=0;i<=4;i++)
    {
        dp[1][i]=-1e9;
    }
    dp[1][0]=0;
    dp[1][1]=-prices[1];
    for(int i=2;i<=n;i++)
    {
        dp[i][0]=dp[i-1][0];
        dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
        dp[i][2]=max(dp[i-1][2],dp[i-1][1]+prices[i]);
        dp[i][3]=max(dp[i-1][3],dp[i-1][2]-prices[i]);
        dp[i][4]=max(dp[i-1][4],dp[i-1][3]+prices[i]);
    }
    int ans=max(dp[n][0],max(dp[n][2],dp[n][4]));
    printf("%d\n",ans);
    return 0;
    
}

 DP33 买卖股票的最好时机(四)

描述

假设你有一个数组pricesprices,长度为nn,其中prices[i]prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你最多可以对该股票有kk笔交易操作,一笔交易代表着一次买入与一次卖出,但是再次购买前必须卖出之前的股票
2. 如果不能获取收益,请返回0
3. 假设买入卖出均无手续费

输入描述:

第一行输入一个正整数 n 和一个正整数 k。表示数组 prices 的长度和 交易笔数

第二行输入 n 个正整数表示数组的所有元素值。

输出描述:

输出最大收益

示例1

输入:

6 3
8 9 3 5 1 3

复制输出:

5

复制说明:

第一天(股票价格=8)买进,

第二天(股票价格=9)卖出,收益为1

第三天(股票价格=3)买进,

第四天(股票价格=5)卖出,收益为2

第五天(股票价格=1)买进,

第六天(股票价格=3)卖出,收益为2

总收益为5。

示例2

输入:

8 2
3 2 5 0 0 3 1 4

复制输出:

7

复制说明:

 

第二天(股票价格=2)买进,

第三天(股票价格=5)卖出,收益为3

第五天(股票价格=0)买进,

第八天(股票价格=4)卖出,收益为4

总收益为7

示例3

输入:

4 4
9 8 4 1

复制输出:

0

复制

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int dp[1005][205];
int prices[1005];
int main()
{
    int n;
    int k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&prices[i]);
    }
    
    
    int s=2*k;
    for(int i=0;i<=s;i++)
    {
        dp[1][i]=-1e9;
    }
    dp[1][0]=0;
    dp[1][1]=-prices[1];
    for(int i=2;i<=n;i++)
    {
        for(int j=0;j<=s;j++)
        {
            if(j==0)
            {
                dp[i][j]=dp[i-1][j];
            }
            else if(j%2==1)
            {
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]-prices[i]);
            }
            else{
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+prices[i]);
            }
        }
    }
    int ans=0;
    for(int i=0;i<=s;i=i+2)
    {
        ans=max(ans,dp[n][i]);
    }
    printf("%d\n",ans);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值