Recursion 动态规划——利润最大化的葡萄酒销售 让我们考虑一下,你有一大堆藏在架子旁边的n种葡萄酒。第i种葡萄酒的价格是圆周率。(不同葡萄酒的价格可能不同)。因为葡萄酒每年都会变得更好,假设今天是第一年,在y年,第i种葡萄酒的价格将是y*pi,即y乘以当年的价值。 你想卖掉你所有的葡萄酒,但你想从今年开始每年只卖出一种葡萄酒。还有一个限制——每年只允许销售货架上最左边或最右边的葡萄酒,不允许重新订购货架上的葡萄酒(即,它们必须保持与开始时相同的顺序)。 你想知道,如果你以最佳顺序销售葡萄酒,你能获得的最大利润是多少 int N; // number of wines int p[N]; // array of wine prices int cache[N][N]; // all values initialized to -1 int profit(int be, int en) { if (be > en) return 0; if (cache[be][en] != -1) return cache[be][en]; int year = N - (en-be+1) + 1; return cache[be][en] = max(profit(be+1, en) + year * p[be],profit(be, en-1) + year * p[en]); }

Recursion 动态规划——利润最大化的葡萄酒销售 让我们考虑一下,你有一大堆藏在架子旁边的n种葡萄酒。第i种葡萄酒的价格是圆周率。(不同葡萄酒的价格可能不同)。因为葡萄酒每年都会变得更好,假设今天是第一年,在y年,第i种葡萄酒的价格将是y*pi,即y乘以当年的价值。 你想卖掉你所有的葡萄酒,但你想从今年开始每年只卖出一种葡萄酒。还有一个限制——每年只允许销售货架上最左边或最右边的葡萄酒,不允许重新订购货架上的葡萄酒(即,它们必须保持与开始时相同的顺序)。 你想知道,如果你以最佳顺序销售葡萄酒,你能获得的最大利润是多少 int N; // number of wines int p[N]; // array of wine prices int cache[N][N]; // all values initialized to -1 int profit(int be, int en) { if (be > en) return 0; if (cache[be][en] != -1) return cache[be][en]; int year = N - (en-be+1) + 1; return cache[be][en] = max(profit(be+1, en) + year * p[be],profit(be, en-1) + year * p[en]); },recursion,data-structures,dynamic-programming,memoization,Recursion,Data Structures,Dynamic Programming,Memoization,时间复杂度:O(n^2)。 我已经找到了这个O(n^2)解。我们能在O(n)区做吗?(更好的时间复杂度)你应该通过出售货架上的所有葡萄酒来找到最佳成本。唯一的限制是你只能挑选左边或右边的葡萄酒(你不能从架子中间挑选酒瓶)。 由于我们可以选择左瓶或右瓶葡萄酒,因此最佳的解决方案顺序将包括左瓶或右瓶 让我们找到一个递归解决方案 只需拿起左边的瓶子,计算一下它的成本 挑选合适的瓶子并计算成本 比较两种成本并选择最大成本 写出基本情况的必要条件 让我们写一个C++程序—— 上述代码的时间复杂度为O(2^

时间复杂度:O(n^2)。
我已经找到了这个O(n^2)解。我们能在O(n)区做吗?(更好的时间复杂度)

你应该通过出售货架上的所有葡萄酒来找到最佳成本。唯一的限制是你只能挑选左边或右边的葡萄酒(你不能从架子中间挑选酒瓶)。
由于我们可以选择左瓶或右瓶葡萄酒,因此最佳的解决方案顺序将包括左瓶或右瓶
让我们找到一个递归解决方案

  • 只需拿起左边的瓶子,计算一下它的成本
  • 挑选合适的瓶子并计算成本
  • 比较两种成本并选择最大成本
  • 写出基本情况的必要条件
  • 让我们写一个C++程序——

    上述代码的时间复杂度为O(2^n),其中
    n
    是货架上酒瓶的数量。
    我们能即兴发挥时间复杂性吗?
    当然。我们基本上是一次又一次地计算一些序列,这可以通过记忆技术避免。
    递归关系将基本相同。除此之外,我们还将记住特定
    i
    j
    的值。因此,我们不必反复计算相同的
    i
    j
    的值。
    C++代码将是-< /p>
    #包括
    使用名称空间std;
    整数查找成本(矢量和方框、矢量和dp、整数i、整数j){
    if(i==j)//基本情况
    dp[i][j]=box[i]*box.size();
    else如果(!dp[i][j]){//
    int n=box.size();
    dp[i][j]=max(查找成本(box,dp,i,j-1)+box[j]*(n-(j-i)),
    求成本(box,dp,i+1,j)+box[i]*(n-(j-i));
    }
    返回dp[i][j];
    }
    无效成本(矢量箱){
    int n=box.size();
    向量dp(n+1,向量(n+1));//初始化dp数组
    cout>n;
    向量盒(n);
    对于(int i=0;i>框[i];
    葡萄酒(盒)成本;
    返回0;
    }
    

    现在,上述代码的时间复杂度将为O(n^2),这远远好于递归方法。

    您能为上述问题提供一个输入和输出示例吗?对我来说,测试代码会更容易,我假设上面问题的一个示例可以输入:-10,1,2,6,7。所以我挑选葡萄酒出售的顺序是这样的-7,6,2,1,10,所以我的总利润是=7*1+6*2+2*3+1*4+10*5=159。如果我错了,请告诉我?@zenwraight是的。考虑这个例子:P[]={ 2, 3, 5,1, 4 },并且解决方案将是2×1 + 4×2 + 1×3 + 3 * 4 + 5 * 5=50,它不可能根据O使用(n)根据我,因为它不会覆盖所有的可能性,DP和O(n^ 2)似乎只是,是解决这个问题的正确方法。
    #include<bits/stdc++.h>
    using namespace std;
    int max_cost(int wine[], int cost, int counter, int i, int j){
    
    
        // Here `counter` keeps track of the number of years
        // `i` is the left indices of the shelf
        // `j` is the right indices of the shelf
        // `cost` is the maximum cost that we have to find
    
    
        if(i > j)
            return cost;
        else if(i == j){
            cost += counter * wine[i];
            return cost;
        }
        else{
            int cost1 = counter * wine[i] + max_cost(wine, 0, counter + 1, i + 1, j);
            int cost2 = counter * wine[j] + max_cost(wine, 0, counter + 1, i, j - 1);
            cost += max(cost1, cost2);
            return cost;
        }
    }
    int main(){
        int n;
        cin >> n;
        int wine[n];
        for(int j = 0; j < n; ++j)
            cin >> wine[j];
        cout << max_cost(wine, 0, 1, 0, n - 1) << endl;
        return 0;
    }
    
    Input1:
    5
    1
    3
    1
    5
    2
    Output:
    43
    
    Input2:
    4
    10
    1
    10
    9
    Output:
    79
    
    #include<bits/stdc++.h>
    using namespace std;
    int find_cost(vector<int>& box, vector<vector<int>>& dp, int i, int j){
        if(i == j)        // base case
            dp[i][j] = box[i] * box.size();
        else if(!dp[i][j]){        // If not calculated so far
            int n = box.size();
            dp[i][j] = max(find_cost(box, dp, i, j - 1) + box[j] * (n - (j - i)), 
                            find_cost(box, dp, i + 1, j) + box[i] * (n - (j - i)));
        }
        return dp[i][j];
    }
    void cost_wine(vector<int> box){
        int n = box.size();
        vector<vector<int>> dp(n + 1, vector<int>(n + 1));  // Initialize dp array
        cout << find_cost(box, dp, 0, n - 1);
        return;
    }
    int main(){
        int n;
        cin >> n;
        vector<int> box(n);
        for(int i = 0; i < n; ++i)
            cin >> box[i];
        cost_wine(box);
        return 0;
    }