Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过最多k次买卖股票获得的最大利润[递推至DP]_Java_Algorithm_Dynamic Programming_Backtracking - Fatal编程技术网

Java 通过最多k次买卖股票获得的最大利润[递推至DP]

Java 通过最多k次买卖股票获得的最大利润[递推至DP],java,algorithm,dynamic-programming,backtracking,Java,Algorithm,Dynamic Programming,Backtracking,与其他DP问题不同,我无法将以下问题分解为重叠的子问题,因此DP解决方案对我来说不是直观的 我看到到处都有自下而上的方法来解决这个问题。我想用自上而下的方法解决这个问题。像任何其他问题一样,我想首先提出递归解决方案,然后使用DP数组缓存重叠的结果。我无法使其重叠,因此无法使DP直观。请帮我把这个转换成DP 下面是我的递归解决方案 private int getMaxProfit(ArrayList<Integer> input, int K) { return getMax

与其他DP问题不同,我无法将以下问题分解为重叠的子问题,因此DP解决方案对我来说不是直观的

我看到到处都有自下而上的方法来解决这个问题。我想用自上而下的方法解决这个问题。像任何其他问题一样,我想首先提出递归解决方案,然后使用DP数组缓存重叠的结果。我无法使其重叠,因此无法使DP直观。请帮我把这个转换成DP

下面是我的递归解决方案

private int getMaxProfit(ArrayList<Integer> input, int K) {
    return getMaxProfit(input, 0, 0, 0, K, K, 0);
}

private int getMaxProfit(ArrayList<Integer> input, int i, int buy, int sell, int bk, int sk, int bal) {
    if (i == input.size() || (bk == 0 && sk == 0)) { // k times Buying, selling done or we reached end
        return buy > sell ? 0 : sell - buy;
    }

    /** If Buying for k times done **/
    if (bk == 0) {
        int neutral = getMaxProfit(input, i + 1, buy, sell, bk, sk, bal + 1);
        int maxProfitBySell = getMaxProfit(input, i + 1, buy, sell + input.get(i), bk, sk - 1, bal - 1);
        return Math.max(neutral, maxProfitBySell);
    }
    /** If Selling for k times done **/
    if (sk == 0) {
        int neutral = getMaxProfit(input, i + 1, buy, sell, bk, sk, bal + 1);
        int maxProfitByBuy = getMaxProfit(input, i + 1, buy + input.get(i), sell, bk - 1, sk, bal + 1);
        return Math.max(neutral, maxProfitByBuy);
    }
    /** we need to buy one stock before we sell it **/
    if (bal == 0) {
        return getMaxProfit(input, i + 1, buy + input.get(i), sell, bk - 1, sk, bal + 1);
    }
    int maxProfitByBuy = getMaxProfit(input, i + 1, buy + input.get(i), sell, bk - 1, sk, bal + 1); // buy
    int neutral = getMaxProfit(input, i + 1, buy, sell, bk, sk, bal + 1); // dont buy or sell
    int maxProfitBySell = getMaxProfit(input, i + 1, buy, sell + input.get(i), bk, sk - 1, bal - 1); //sell
    return Math.max(neutral, Math.max(maxProfitByBuy, maxProfitBySell));
}
private int getMaxProfit(数组列表输入,int K){
返回getMaxProfit(输入,0,0,0,K,K,0);
}
私有int-getMaxProfit(数组列表输入、int-i、int-buy、int-sell、int-bk、int-sk、int-bal){
如果(i==input.size()| | |(bk==0&&sk==0)){//k次买入、卖出完成或我们到达终点
返回买入>卖出?0:卖出-买入;
}
/**如果买了k倍就完成了**/
如果(bk==0){
int neutral=getMaxProfit(输入,i+1,买入,卖出,bk,sk,bal+1);
int maxproitbysell=getmaxproit(输入,i+1,买入,卖出+input.get(i),bk,sk-1,bal-1);
返回Math.max(中性,maxproitbysell);
}
/**如果以k倍的价格出售,则完成**/
如果(sk==0){
int neutral=getMaxProfit(输入,i+1,买入,卖出,bk,sk,bal+1);
int maxproitbybuy=getmaxproit(输入,i+1,购买+输入。获取(i),出售,bk-1,sk,bal+1);
返回Math.max(中性,maxproitbybuy);
}
/**我们需要先买一只股票,然后再出售**/
如果(bal==0){
返回getMaxProfit(输入,i+1,买入+输入。获取(i),卖出,bk-1,sk,bal+1);
}
int maxproitbybuy=getmaxproit(输入,i+1,购买+输入。获取(i),出售,bk-1,sk,bal+1);//购买
int neutral=getMaxProfit(输入,i+1,买入,卖出,bk,sk,bal+1);//不买入或卖出
int maxproitbysell=getmaxproit(输入,i+1,买入,卖出+input.get(i),bk,sk-1,bal-1);//卖出
返回Math.max(中性,Math.max(maxproitbybuy,maxproitbysell));
}

要转换为自底向上的方法,如果递归方法首先是自上而下制定的(这意味着调用的参数是递减的),并且参数状态和结果之间有明确的关联,那么将有助于更加直观和简单。因为在这个问题中,事务是连续的,每个事务由两部分组成,所以我们可以实现这一点的一种方法是将K加倍,并使用其当前奇偶校验来指示事务中的状态

这里是用JavaScript自上而下的注释,使用问题描述中共享的Geeks for Geeks链接中的输入示例。(请注意,此处的“销售”在其各自的“购买”之前进行检查。)

//奇数k表示第(k/2)次购买已完成
函数f(A,k,i=A.length-1){
//所有交易都完成了
如果(k==0)
返回0
//我们在价目表的开头
如果我们处于交易的中间,
//强制关联的“购买”
如果(i==0)
返回k&1?-A[0]:0
//当前k为奇数,因此我们已完成“卖出”-
//选择记录关联的“购买”或跳过
if(k&1){
返回Math.max(
-A[i]+f(A,k-1,i-1),//买
f(A,k,i-1)//跳过
)
//目前的k值为偶数,因此我们已完成“买入”或“卖出”
//是否“静止”-选择录制新的“卖出”或跳过
}否则{
返回Math.max(
A[i]+f(A,k-1,i-1),//出售
f(A,k,i-1)//跳过
)
}
}
变量输入=[
[[10, 22, 5, 75, 65, 80], 2], // 87
[[12, 14, 17, 10, 14, 13, 12, 15], 3], // 12
[[100, 30, 15, 10, 8, 25, 80], 3], // 72
[[90, 80, 70, 60, 50], 1] // 0
]
for(让[A,K]个输入){
log(`A:${A},K:${K}`)
log(f(A,2*K))//用双倍K调用

}
这里是非递归、非DP解决方案。时间复杂度-O(n)

int calculateMaxProfit(int[]股票价格,int maxTransactionAllowed)
{
int j=0;
int maxLen=stockPrice.length;
国际利润=0;
int transactionCount=1;
int buy=-1;
int sell=-1;
而((j+1股价[j]))
{
j++;
}
//在最后一次允许交易的情况下,获取尚未遍历的价格的最大值
if(transactionCount==MaxTransactionLowed){
如果(股价[j]>=股价[卖出]){
sell=j;
}
}否则{
sell=j;
}
if(j+1
int calculateMaxProfit(int[] stockPrice, int maxTransactionAllowed)
{

    int j=0;
    int maxLen = stockPrice.length ;
    int profit = 0;
    int transactionCount =  1;
    int buy = -1;
    int sell = -1;

    while( (j + 1 < maxLen - 1 && transactionCount <= maxTransactionAllowed) )
    {
        // find lowest price to buy before price goes up again
        while(j+1 < maxLen && ( stockPrice[j+1] < stockPrice[j]))
        {
            j++;
        }

        // In case of last allowed transaction get minimum of the prices yet to be traversed
        if( transactionCount == maxTransactionAllowed) {
            if( stockPrice[buy] >= stockPrice[j]){
                buy = j;
            }
        }else{
            buy = j;
        }

        // find highest price to sell before a downward trend
        while(j+1 < maxLen && ( stockPrice[j+1] > stockPrice[j]) )
        {
            j++;
        }
        // In case of last allowed transaction get max of the prices yet to be traversed
        if( transactionCount == maxTransactionAllowed){
            if(  stockPrice[j] >= stockPrice[sell] ){
                sell = j;
            }
        }else {
            sell = j;
        }


        if( j+1 < maxLen && transactionCount < maxTransactionAllowed )
        {
            profit += stockPrice[sell] - stockPrice[buy];
            buy = j+1;
            sell = j+1;
            transactionCount++;
        }
    }
    profit += stockPrice[sell] - stockPrice[buy];
    return profit;
}