木板最优切割利润最大_最多进行K笔交易的股票最大买卖利润

木板最优切割利润最大

This is a very popular interview problem to find maximum profit in stock buying and selling with at most K transactions. This problem has been featured in the interview rounds of Amazon.

这是一个非常受欢迎的面试问题,目的是在最多进行K笔交易时,在股票买卖中获得最大利润 。 亚马逊的采访回合中已经提到了这个问题。

Problem statement:

问题陈述:

In stock market, a person buys a stock and sells it on some future date. Given the stock prices of N days in form of an array Amount and a positive integer K, find out the maximum profit a person can make in at most K transactions. A transaction is buying the stock on some day and selling the stock at some other future day and new transaction can start only when the previous transaction has been completed.

在股票市场中,一个人购买股票并在将来的某个日期将其出售。 给定N天的股票价格( 数量为数组)和正整数K ,找出一个人最多可以进行K笔交易的最大利润。 某笔交易在某天买入股票,而在将来的另一天卖出股票,只有在上一笔交易完成后才能开始新交易。

    Input:
    K=3
    N=7

    Stock prices on N days:
    10 25 38 40 45 5 58

    Output:
    88

Example:

例:

    Number of maximum transactions: 3
    Total number of days, N: 7

    To achieve maximum profit:
    Stock bought at day1    (-10)
    Stock sold at day5      (+45)
    Stock bought at day6    (-5)
    Stock sold at day7      (+58)

    Total profit = 88
    Total transactions made = 2

Explanation:

说明:

Let there are N number of days for transactions, say x1, x2, ..., xn

设交易的天数为N ,例如x 1 ,x 2 ,...,x n

Now for any day xi

现在任何一天x

  1. Don't do any transaction on the day xi

    x 当天不做任何交易

  2. Transact on day xi, i.e., buy stock on some day xj and sell on day xi where j<i and i,j Є N

    一天的Transact X I,即,在某些天×j和卖出日股购买X I其中j <iI,JЄñ

Total number of transactions can be made at most = K

最多可以进行的交易总数= K

Now we can formulate the maximum profit case using above two condition.

现在,我们可以使用以上两个条件来制定最大获利情况。

Let,

让,

    f(t,i)=maximum profit upto ith day and t transactions

Considering the above two facts about xi

考虑关于x i的上述两个事实

    f(t,i)=f(t,i-1)  if there is no transaction made on day xi ...(1)
        Max(f(t-1,j)+amount[i]-amount[j])       
        where j<i and i,j Є N if there is transaction  on day xi ...(2)
    Obviously, to maximize the profit we would take the maximum of (1)  and (2)

    Number of maximum transactions: 3
    Total number of days, N: 7
    Stock prices on the days are:
    10 25 38 40 45 5 58

Below is a part of recursion tree which can show that how many overlapping sub problems there will be.

下面是递归树的一部分,它可以显示将有多少个重叠的子问题。

recusrion tree 1


Figure 1: Partial recursion tree to show overlapping sub-problems

图1:部分递归树显示重叠的子问题

So we need dynamic programming...

所以我们需要动态编程...

Problem Solution

问题方案

Recursive Algorithm:

递归算法:

    Function(t, i): //f(t, i)
        If i=0
            f(t, i)=0
        If t=0
            f(t, i)=0

        f(t, i)= f(t, i-1); //no transaction on day xi
        For j =0: i
            Find max(f(t-1,j) + amount(i)- amount(j)
        End For
        If the maximum found > f(t, i)
            update f(t, i)
        End IF
    Return f(t, i)

Conversion to DP

转换为DP

    For tabulation we need a 2D array, DP[k+1][n] to store f(t,i)

    Base case,
    for i 0 to k,   DP[i][0]=0 //no profit on 0th day
    for i 0 to n-1,   DP[0][j]=0 //no profit on 0 transaction


    To fill the higher values,
    for t=1 to k
        for i =1 to n-1
            DP[t][i]=DP[t][i-1]
            for j= 0 to i-1 //buying on jth day and selling on ith day   
                DP[t][i]=max(DP[t][i],DP[t-1][j]+ amount[i] –amount[j])
            End for
        End for
    End for
    Result would be f(k,n) that is value of DP[k][n-1]

Initial DP table

初始DP表

    DP[4][7] //K=3, N=7

DP Table

Try yourself to compute the DP table manually following the above algorithm and find out the result. Take some small example if necessary.

尝试按照上述算法手动计算DP表并找出结果。 如有必要,举一些小例子。

C++ implementation:

C ++实现:

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

int Max_profit(vector<int> amount, int n, int k)
{
    int DP[k + 1][n];
    memset(DP, 0, sizeof(DP));

    //on 0th day
    for (int i = 0; i <= k; i++)
        DP[i][0] = 0;
    //on 0 transaction made
    for (int i = 0; i <= n; i++)
        DP[0][i] = 0;

    for (int t = 1; t <= k; t++) {
        for (int i = 1; i < n; i++) {
            DP[t][i] = DP[t][i - 1];
            int maxV = INT_MIN;
            //buying on jth day and selling on ith day
            for (int j = 0; j < i; j++) {

                if (maxV < DP[t - 1][j] + amount[i] - amount[j])
                    maxV = DP[t - 1][j] + amount[i] - amount[j];
            }
            if (DP[t][i] < maxV)
                DP[t][i] = maxV;
        }
    }
    return DP[k][n - 1];
}

int main()
{
    int n, item, k;

    cout << "Enter maximum no of transactions:\n";
    cin >> k;
    cout << "Enter number of days\n";
    cin >> n;
    vector<int> amount;
    cout << "Enter stock values on corresponding days\n";
    for (int j = 0; j < n; j++) {
        scanf("%d", &item);
        amount.push_back(item);
    }

    cout << "Maximum profit that can be achieved: " << Max_profit(amount, n, k) << endl;

    return 0;
}

Output

输出量

Enter maximum no of transactions:
3
Enter number of days
7
Enter stock values on corresponding days
10 25 38 40 45 5 58
Maximum profit that can be achieved: 88


翻译自: https://www.includehelp.com/icp/maximum-profit-in-stock-buy-and-sell-with-at-most-k-transaction.aspx

木板最优切割利润最大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值