首页 > 试题广场 >

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

[编程题]买卖股票的最好时机(四)
  • 热度指数:1772 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
假设你有一个数组,长度为,其中是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你最多可以对该股票有笔交易操作,一笔交易代表着一次买入与一次卖出,但是再次购买前必须卖出之前的股票
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
dp+状态压缩
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n, k;
    cin>>n>>k;
    vector<int> prices(n);
    for(int i=0; i<n; i++){
        cin>>prices[i];
    }
    vector<int> dp(vector<int>(2*k+1, 0));
    for(int i=0; i<=2*k; i++){
        dp[i] = ((i&1)==0) ? 0 : -prices[0];
    }
    for(int i=1; i<n; i++){
        for(int j=2*k; j>0; j--){
            if((j&1)==1){ //买入
                dp[j] = max(dp[j], dp[j-1]-prices[i]);
            }else{ //卖出
                dp[j] = max(dp[j], dp[j-1]+prices[i]);
            }
        }
    }
    cout<<dp[2*k];
    return 0;
}


编辑于 2024-01-01 18:17:17 回复(0)
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        String str1=scan.nextLine();
        String[] str11=str1.split(" ");
        int[] NandK=new int[str11.length];
        for(int i=0;i<str11.length;i++){
            NandK[i]=Integer.valueOf(str11[i]);
        }
        int n=NandK[0];
        int k=NandK[1];
        String str2=scan.nextLine();
        String[] str22=str2.split(" ");
        int[] nums=new int[str22.length];
        for(int i=0;i<nums.length;i++){
            nums[i]=Integer.valueOf(str22[i]);
        }
       
        //最多K笔交易
        if(nums.length==1){
            System.out.println(0);
            return;
        }
        int[][] dp=new int[nums.length][2*k+1];//2笔交易5个状态
       /* dp[0][0]=0;  //奇偶,偶数初始化为0,奇数初始化为-nums[0]
        dp[0][1]=-nums[0];
        dp[0][2]=0;
        dp[0][3]=-nums[0];
        dp[0][4]=0;  */
        //初始化完毕
        for(int i=0;i<2*k+1;i++){  //注意这里i的取值范围为0 ~(2*k+1)
            if(i%2==0){
                dp[0][i]=0;
            }else{
                dp[0][i]=-nums[0];
            }
        }
        for(int i=1;i<nums.length;i++){
            for(int p=1;p<2*k+1;p++){
                if(p%2==1){
                    dp[i][p]=Math.max(dp[i-1][p],dp[i-1][p-1]-nums[i]);//买入
                }else{
                    dp[i][p]=Math.max(dp[i-1][p],dp[i-1][p-1]+nums[i]);//卖出
                }
            }
        }
        System.out.println(dp[nums.length-1][2*k]);
    }
}

发表于 2023-07-11 13:50:17 回复(0)
import java.util.Arrays;
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            int k = in.nextInt();
            int[] price = new int[n];
            for (int i = 0; i < n; i++) price[i] = in.nextInt();
            int sum = 0;
            int[] buy = new int[k + 1];
            int[] sell = new int[k + 1];
            Arrays.fill(buy, Integer.MIN_VALUE);
            Arrays.fill(buy, Integer.MIN_VALUE);
            for (int i = 0; i < n; i++) {
                for (int j = 1; j <= k; j++) {
                    buy[j] = Math.max(buy[j], sell[j - 1] - price[i]);
                    sell[j] = Math.max(sell[j], buy[j] + price[i]);
                }
            }
            System.out.println(sell[k]);
        }
    }
}

发表于 2022-09-22 15:20:23 回复(0)
#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    vector<int> vi(n, 0);
    for (int i = 0; i < n; ++i) {
        cin >> vi[i];
    }
    int res = 0;
    vector<pair<int, int>> dp(k+1);
    dp[0] = make_pair(0, 0);
    for (int j = 1; j <= k; ++j) {
            dp[j] = make_pair(-vi[0], 0);
    }
    for (int i = 1; i < n; ++i) {
        for (int j = 1; j <= k; ++j) {
            dp[j].first = max(dp[j].first, dp[j-1].second -vi[i]);
            dp[j].second = max(dp[j].second, vi[i] + dp[j].first);
        }
    }
    res = dp[k].second;
    cout << res;
}
// 64 位输出请用 printf("%lld")

发表于 2022-09-16 23:22:02 回复(0)
O(n*n*k)的简单粗暴写法,递归超时
#include<iostream>
#include<algorithm>
using namespace std;

int prices[1009];
int zero[1009];
int dp[1009][109];

int main(){
  int n,k,res=0;
  cin>>n>>k;
  for(int i=0;i<n;i++){
    cin>>prices[i];
  }
  for(int i=0;i<n;i++){
    res=max(res,dp[i][k]);
    int min_i2j=prices[i];
    for(int j=i+1;j<n;j++){
      min_i2j=min(min_i2j,prices[j]);
      for(int h=1;h<=k;h++){
        dp[j][h]=max(dp[j][h],dp[i-1][h-1]+prices[j]-min_i2j);
      }
    }
  }
  cout<<res<<endl;
}

// int cache(int (*f)(int,int),int n,int k){
//   if(data[n][k]==0){
//     data[n][k]=f(n,k);
//   }
//   return data[n][k];
// }

// // k次交易机会,n点卖出
// int dp(int n,int k){
//   if(k==0) return 0;

//   int maxgain=0;
//   for(int i=0;i<n;i++){
//     int currgain=cache(dp,i,k-1)+prices[n]-rangemin[i][n];
//     maxgain=max(maxgain,currgain);
//   }
//   return maxgain;
// }



发表于 2022-08-31 13:51:37 回复(0)
#include<bits/stdc++.h>
using namespace std;
int maxProfit(vector<int>&prices,int k){
    int n=prices.size();
    k=min(k,n/2);
    //2k+1种状态
    vector<int>buy(k+1);
    vector<int>sell(k+1);
    buy[0]=-prices[0];
    sell[0]=0;
    for(int i=1;i<=k;i++){
        buy[i]=sell[i]=INT_MIN/2;
    }
    for(int i=1;i<n;i++){
        buy[0]=max(buy[0],sell[0]-prices[i]);
        for(int j=1;j<=k;j++){
            buy[j]=max(buy[j],sell[j]-prices[i]);
            sell[j]=max(sell[j],buy[j-1]+prices[i]);
        }
    }
    return *max_element(sell.begin(),sell.end());
}
int main(){
    int n,k;cin>>n>>k;
    vector<int>prices(n);
    for(int i=0;i<n;i++)cin>>prices[i];
    cout<<maxProfit(prices,k);
}

发表于 2022-04-01 10:05:16 回复(0)