Topcoder SRM 149 D2 Q3:定价

时间:2016-02-11 05:40:28

标签: c++ algorithm

以下问题来自Topcoder的SRM 149.即使在查看解决方案之后,我也不知道如何解决这个问题。我一直在尝试这个问题一个半小时,从解决方案开始再过一个小时,但我无法理解它在做什么......

如果有人能就这个解决方案的工作方式给我一些提示,我将非常感激。

问题:http://topcoder.bgcoder.com/print.php?id=250

解决方案:http://apps.topcoder.com/forums//?module=Thread&threadID=575120&start=0

在SRM 149(第二级第三级)中使用的TopCoder问题“定价”

问题陈述 最简单形式的市场差异化是为同一产品向不同客户收取不同价格的系统。为了最大化总销售收入,我们希望单独向每个客​​户收费,收取客户愿意支付的最高价格。通常我们必须将客户划分为几个组,并向组中的每个人收取相同的价格(例如商务舱,经济舱等)。 我们列出了我们产品的所有潜在客户以及每位客户愿意支付的最多客户。我们决定将它们区分为四个或更少(非重叠)组。每组中的每个人都将获得相同的价格。我们的目标是以最佳方式选择团体和价格,以最大化我们的总销售收入。

创建一个类别,其中包含一个方法maxSales,该方法采用包含每个潜在客户愿意支付的最高价格的int []价格,并通过将我们的客户区分为四个或更少的组来返回我们可以产生的最大销售收入

定义

类:定价 方法:maxSales 参数:int [] 返回:int 方法签名:int maxSales(int [] price) (确保你的方法是公开的)

约束

  • 价格必须包含1到50个元素
  • 每个价格元素必须介于0到1000之间

实施例

0)

{9,1,5,5,5,5,4,8,80} 返回:120 向愿意支付80的一个客户收取80。 向愿意支付8或9的2位客户收取8。 向愿意支付5的4位客户收取5。 向愿意支付4的客户收取4。 总销售收入= 1 * 80 + 2 * 8 + 4 * 5 + 1 * 4。 (我们可以将愿意支付1的客户放入这些组中,因为他不会以这些价格购买任何东西。) 1)

{17,50,2} 回报:69 我们只使用三组,每组包含一个客户。我们向每位客户收取她愿意支付的最多费用。总销售收入= 1 * 17 + 1 * 50 + 1 * 2 2)

{130,110,90,13,6,5,4,3,0} 返回:346 向愿意以4到13之间支付4个价格的4个客户收取费用,从而从他们那里获得总共16个。然后向愿意付出很多钱的三位顾客中的每一位收取最多费用。 4 * 4 + 90 + 110 + 130 = 346

SOLUTION:
Arrays.sort(price);
   int ret = 0;
   for(int i = 0; i<price.length; i++){
      for(int j = i; j<price.length; j++){
         for(int k = j; k<price.length; k++){
            for(int m = k; m<price.length; m++){
               int rev = 0;
               for(int n = 0; n<price.length; n++){
                  if(price[n]>=price[m]){
                     rev+=price[m];
                  }else if(price[n]>=price[k]){
                     rev+=price[k];
                  }else if(price[n]>=price[j]){
                     rev+=price[j];
                  }else if(price[n]>=price[i]){
                     rev+=price[i];
                  }
               }
               ret=Math.max(ret,rev);
            }
         }
      }
   }
   return ret;

2 个答案:

答案 0 :(得分:2)

它的蛮力。

每组{i,j,k,m}是四组价格的选择。 n循环计算该选项的收入,ret跟踪最高收入。

(这个解决方案是O(N 5 )。我认为O(N)是可能的。)

答案 1 :(得分:0)

我认为我会分享我的解决方案,尽管这是一个痛苦和模糊的蛮力(正如Beta建议的那样)。我使用itertools来获取定价组合而不是嵌套循环 - 当我明确指定可能的组大小时,这感觉更合乎逻辑(参见range(0, MAX_GROUPS))。

注意我只测试了Topcoder Arena中的基本测试用例,而不是来自SRM 149的所有测试用例。最终的修剪代码是hacky。

import itertools

MAX_GROUPS = 4

# price ~ (int, int, ...)
def maxSales(price):

    # Returns from given sales combination
    def _ret(grp):
        return sum([len(g) * g[0] for g in grp])

    if len(price) <= MAX_GROUPS:
        return sum(price)

    # Sort price listing ascending, and then split into 1-4 groups
    price = sorted(price)
    grp_max_ret, grp = -1, []
    for i in range(0, MAX_GROUPS):
        for splits in itertools.combinations(range(1, len(price)), i):
            result = []
            prev = None
            for split in itertools.chain(splits, [None]):
                result.append(list(price[prev:split]))
                prev = split
            result_ret = _ret(result)
            # Keep track of top performer
            if result_ret > grp_max_ret:
                grp_max_ret, grp = result_ret, result

    # Trim first group, which effectively gives freebies
    pre_trim_grp = grp[:]
    for _ in range(len(pre_trim_grp[0])-1):
        trim_grp = pre_trim_grp[:]
        trim_grp[0].pop(0)
        grp_max_ret = max(grp_max_ret, _ret(trim_grp))

    return grp_max_ret