【问题标题】:Find the maximum profit when selling theatre seats在出售剧院座位时找到最大利润
【发布时间】:2023-02-04 02:12:57
【问题描述】:

在一场剧院演出中,有 N 个座位 [1,2,3,...N],每个座位的价格都不同,因此第 i 个票的价格为 A[i]。人们成群结队地来,想坐在一起。数组 B 的索引指示相应的组大小。通过最佳座位计划,确定所有者可以获得的最大利润。

例如:

N=6;

A = [9, 2, 5, 1, 2, 3]

B = [2, 3]

Ans: 数组 A 可以被划分为 9 + 2 + 5 = 16 和 2+3=5。因此售出机票的成本可以是16+5=21

【问题讨论】:

  • 你试过什么?你在哪里遇到问题?
  • N、价格和团体人数的限制是什么?
  • @AbhinavMathur 我正在考虑应用滑动窗口方法,但我不知道如何在多个窗口滑动的同时保持每个窗口的最大值。
  • 一种方法是尝试数组 B 的所有排列。在示例中,只有两个排列:[2,3] 和 [3,2]。然后尝试将第一组放在每个有效位置。有效位置是为其他组留出足够空间的位置。滑动窗口可用于快速计算每个头寸的利润。可以使用记忆,因为会有共同的子问题需要解决。
  • @Fire'NLightnin' 如果我明白你在说什么,那我不同意。反例是A=[9,9,0,9,9,0,1,1,1,1,1],组大小为B=[5,2,2]。如果你把 5 组放在第一位,并最大化它的利润,你最终会得到 [9,9,0,9,9], [1,1], [1,1],利润为 40。但最佳答案是 [9,9], [9,9], [1,1,1,1,1],利润为 41。简而言之,我不认为有任何最优的贪心算法。

标签: algorithm data-structures sliding-window


【解决方案1】:

您必须按大小对组进行排序:从最大到最小。较大的组总是会更好地首先找到他们的最大窗口总和。例如,如果您有大小 [2,3] 的组和 [9,9,2,1,9,9] 的定价表,那么如果您先进行两个一组,您的算法可能会给您 [{ 9,9},2,1,9,9]。这将迫使您的 3 人小组进入利润较低的位置。
对小组进行排序后,您将必须跟踪每个小组的座位安排。这样,您就可以检查以确保您没有试图让一群人坐在已经被占用的座位上,如果是这样的话,您可以跳过那些已经占用的座位。 此外,您还需要跟踪每个窗口的利润,以便事后汇总。
我已经为这个问题编写了工作代码,我需要一个 3 层嵌套循环,所以我推荐有用的变量名(不仅仅是 i、j 和 k)。
编辑:此外,就像用户在 cmets 中所说的那样,确保消除任何没有为其他组留出足够空间的展示位置。

【讨论】:

  • 你能为这种方法链接你的代码吗?
  • 您能否从数学上证明,为最大群体选择“最佳安排”的解决方案也将是全球最佳解决方案?
【解决方案2】:

#滑动窗口和蛮力#
时间复杂度有点 O(N*M),其中 M 是数组 B 的大小。
方法->
1.对数组B进行降序排列。
2.现在循环遍历数组B。
3.假设第一组的大小为k,然后为该组找到最大和和大小为k的子数组
4.之后缩小主数组 A 并删除上一步中使用的元素。
通过这种方式,您的主阵列将不断缩小,您将获得最大利润。

long long solve(int N,int M,vector<int> A,vector<int> B)
{
    sort(B.rbegin(),B.rend());
    long long profit=0;
    for(int it=0;it<M;it++)
    {
        int k=B[it];
        //Find k size window with max sum
        long long sum=0;
        long long mx=0;//for storing max sum
        int s=0,e=0;//for storing the window with max sum
        int i=0,j=0;
        while(j<N)
        {
            sum+=(long long)A[j];
            //shrink window
            if(j-i+1>k)
            {
                while(j-i+1>k)
                {
                    sum-=A[i++];
                }
            }
            if(sum>mx)
            {
                mx=sum;
                s=i,e=j;
            }
            j++;
        }
        profit+=mx;
        vector<int> v;
        for(int i=0;i<s;i++) v.push_back(A[i]);
        for(int i=e+1;i<N;i++) v.push_back(A[i]);
        A=v;
        N=A.size();
    }
    return profit;
}

【讨论】:

  • 你好!由于两个原因,该算法将不起作用。首先,这不是蛮力,而是贪婪的,因为它只考虑最佳个人解决方案对于每个组。其次,在删除数组元素“A”并缩小数组后,您忽略了不应拆分组的事实。
猜你喜欢
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多