在你的问题的问题都可以转化为一个更好的问题陈述的例子:
由于股票价格的每一天对于n天,通过完成一次交易,一个人可以获得的最大利润是多少。一笔交易意味着该人可以在一天内买入一只股票,并在稍后的日期卖出。
分而治之的解决方案:让我们看看我们是否能够通过拆分输入了一半,每个子阵列解决这个问题,那么两者结合起来解决这个问题。事实证明,我们实际上可以做到这一点,并且可以高效地做到!直觉如下。如果我们有一天的时间,最好的选择是当天买入,然后在同一天卖出,无利可图。否则,将数组分成两半。如果我们考虑最佳答案可能是什么,它必须位于三个位置之一:
- 正确的买入/卖出对在上半部分完全发生。
- 正确的买入/卖出对在下半年完全发生。
- 正确的买入/卖出对发生在两个半部分 - 我们在上半年买入,然后在下半年卖出。
我们可以通过在第一和第二半上递归地调用我们的算法来获得(1)和(2)的值。对于期权(3)而言,获得最高利润的方法是在上半年的最低点买入,并在下半年卖出最高点。通过对输入进行简单的线性扫描并找到两个值,我们可以在两半中找到最小值和最大值。然后这给了我们一个算法,下面的重现:
T(n) = 2T(n/2) + O(n)
T(n) = O(nlogn)
这是一个简单的Python实现。它非常简单易懂,它也很容易转换为C++:
def DivideAndConquerSingleSellProfit(arr):
# Base case: If the array has zero or one elements in it, the maximum
# profit is 0.
if len(arr) <= 1:
return 0;
# Cut the array into two roughly equal pieces.
left = arr[ : len(arr)/2]
right = arr[len(arr)/2 : ]
# Find the values for buying and selling purely in the left or purely in
# the right.
leftBest = DivideAndConquerSingleSellProfit(left)
rightBest = DivideAndConquerSingleSellProfit(right)
# Compute the best profit for buying in the left and selling in the right.
crossBest = max(right) - min(left)
# Return the best of the three
return max(leftBest, rightBest, crossBest)
编辑:这里是上述算法
#include <iostream>
#include <algorithm>
using namespace std;
int calculateMin(int a[], int low, int high)
{
int i,mini;
mini = a[low];
for(i=low;i<=high;i++)
{
if(a[i]<mini)
{
mini = a[i];
}
}
return mini;
}
int calculateMax(int a[], int low, int high)
{
int i,maxi;
maxi = a[low];
for(i=low;i<=high;i++)
{
if(a[i]>maxi)
{
maxi = a[i];
}
}
return maxi;
}
int calculateMaxDiff(int a[], int low, int high)
{
if(low>=high)
return 0;
int mid = (low+high)/2;
int leftPartition = calculateMaxDiff(a,low,mid);
int rightPartition = calculateMaxDiff(a,mid+1,high);
int left = calculateMin(a,low,mid); // calculate the min value in the left partition
int right = calculateMax(a,mid+1,high); // calculate the max value in the right partition
return max(max(leftPartition, rightPartition), (right - left));
}
int main() {
int arr[] = {12, 9, 18, 3, 7, 11, 6, 15, 6, 1 ,10};
int len = sizeof(arr)/sizeof(arr[0]);
int ans = calculateMaxDiff(arr, 0, len-1);
cout << "Maximum Profit: " <<ans<<endl;
return 0;
}
希望它可以帮助C++实现!
这是什么甚至试图实现?你有样品使用情况和预期结果吗? – tadman
@tadman我添加了一个示例输出 – RRP
所以你需要计算整个数组的最大*和*最小值。这里不需要递归,只需要两个变量和一个迭代循环。事实上,我不认为你可以(有效地)用递归来解决这个问题。 – tadman