使用c中n个项目中的至少k来计算最终产品的预期成本

时间:2014-05-03 14:09:56

标签: c algorithm

假设我有4个项目,我必须选择至少1个项目来制作产品。 我的每件商品都有相应的成本作为Item1 - > 4,Item2 - > 7,Item3 - > 2,Item4 - > 5.我必须找到最终产品的预期成本意味着所有可能组合的平均值项目使用,如果我只使用1项,那么成本可能是4,7,2,5,如果我使用2项,成本将是4 + 7,4 + 2,4 + 5,7 + 2,7 + 5,2 + 5和类似的所有组合使用三个项目和4 + 2 + 7 + 5使用四个项目。添加所有组合和他们没有。组合给了我最终产品的预期成本。所以我想找到所有这些组合的总和然后我该怎么做呢?

我认为递归将用于计算这些组合,但无法应用???

5 个答案:

答案 0 :(得分:2)

您可以使用位操作,而不是使用递归来生成所有可能的子集。对于具有4个项目的示例,存在2 ^ 4个可能的子集。因此,您可以使用4位二进制数表示这些2 ^ 4子集。二进制数将从0到2 ^ 4-1 = 15计数。对于每个数字,您检查4位的状态。如果设置了该位,则该元素包含在该子集中,否则不包括。

您可以以Working Java Program

的形式轻松实现此逻辑
        int[] arr = {4 , 7 , 2 , 5};
        double ans = 0;
        int numCombinations = (int)Math.pow(2, arr.length);

        // Iterate over all the subsets represented in the form of binary numbers
        for(int i=0; i<numCombinations; i++){
            int sum = 0;

            // check whether a bit is set or not. If the bit is set, then that 
            // number is present in that subset, else it is not present.
            for(int bit=0; bit<arr.length; bit++){
                if( (i & (1<<bit)) != 0){
                    sum += arr[bit];
                }
            }
            ans += (double)sum;
        }

        //Divide by numCombinations-1 as we are not considering the empty subset{}
        System.out.println(ans/(numCombinations-1));

对于给定的情况,该程序正确计算答案为9.6。

运行时间O(n.2^n)

修改:更好的解决方案

假设您正在生成n个元素的所有子集。现在元素有两种可能性。它将被包括在内,或者不包括在内。假设您拥有所有n-1个元素子集。对于所有这些n-1个元素子集,您将执行上述两种情况之一,即。你将包括第n个元素。因此,我们可以说如果我们总共有M个子集,那么任何元素都会出现M / 2次

在给定的情况下,M是2 ^ n,因为我们正在生成所有子集。所以任何元素都会出现2 ^(n-1)次。

所以所有子集中所有数字的总和将是

  

所有子集的数量之和= arr [0] * 2 ^(n-1)+ arr 1 * 2 ^(n-1)+ ....... arr [n] * 2 ^(N-1)

将其除以子集的数量将给出答案。

  

子集总数= 2 ^ n - 1.

我们正在减去1,因为我们没有考虑空子集{}。

因此,对于给定的案例,答案将成为 (4 + 7 + 2 + 5)* 2 ^(n-1)/(2 ^ n - 1)= 9.6

运行时间:O(n)

答案 1 :(得分:1)

这个问题有很多对称性,这意味着你不需要一个程序来解决它。

(1)有4种可能的&#34;产品&#34; 1部分 (2)有6个(4 * 3/2)产品,2个部分
(3)有4个(4 * 3 * 2 /(3 * 2 * 1)产品,3个部分 (4)有一个产品有4个部分。

组合总数= 15(我假设我们可以忽略&#34;一个产品零件零件&#34;)。

现在,在每种情况下,每个项目的使用次数相同:

对于(1),你每使用1/4的时间
对于(2),你每使用1/2的时间
对于(3),你每使用3/4的时间
对于(4),你一直都在使用它们。

所以每个部分总共使用1 + 3 + 3 + 1 = 15个配置中的8个。

因此&#34;预期成本&#34;是

(8/15) * (4+7+2+5) = 18 * 8 / 15 = 9.6

编辑如果没有明确计算,你怎么能得到数字8/15?好吧,您可以注意到您可以将可能的组合(部分使用或部分未使用)视为具有四位数的二进制数(因为有四个部分) - 这已在其他答案中指出。当您列出从0b00000b1111的所有二进制数时,您知道每个位置将具有相同数量的1和0 - 每个位数为8。如果没有&#34;而不是产品&#34;,你会发现每个产品仍然有8个 - 因此15个中有8个。

答案 2 :(得分:0)

如果您将项目表示为整数中的设置位,则可以简单地从1到15进行迭代并使用位操作来确定成本。
在(伪)C

cost = 0.0;
for(i=1;i<=15;++i)
{
  for(j=0;j<4;++j)
  {
    if(i & (1<<j)) cost += item_cost[j];
  }
}
average = cost / 15.0;

修改

假设您想在最少数量的项目上放置k的界限

n = 0;
cost = 0.0;
for(i=1;i<=15;++i)
{
  sum = 0.0;
  used = 0;
  for(j=0;j<4;++j)
  {
    if(i & (1<<j))
    {
     sum += item_cost[j];
     ++used;
    }
  }

  if(used>=k)
  {
    cost += sum;
    ++n;
  }
}
average = cost / n;

答案 3 :(得分:0)

没有任何东西可以将您的物品彼此区分开来,并且组合的集合是完全对称的,因此在所有可能组合的集合中,每个项目的选择次数与其他项目的次数相同。

因此,我们可以通过将每件商品的成本替换为平均商品成本来简化问题,然后只计算所有组合中所选商品的数量和组合总数。这使得组合的平均成本:

average item cost * total number of items
-----------------------------------------
      total number of combinations

k = 1的情况下,组合总数为2n-1,所有组合中的项目总数为n×2n-1

答案 4 :(得分:0)

您的问题可以用数学方法解决 -

让&#39; n&#39;总不是。元素和&#39; K&#39;不。组合考虑的项目。

SUM =数组中所有元素的总和

COMBINATIONS =从n中选择的k个项目,即(n C k)

FREQUENCY =所有组合中每个项目的频率,即(n-1 C k-1)

所以解决方案是 - Ans = SUM * FREQUENCY / COMBINATIONS

简化后 - Ans = SUM * k / n

package com.kvvssut.misc;

public class AverageOfCombinations {

    public static void main(String[] args) {
        System.out.println(getAverageOfAllKCombinations(new int[]{4,7,2,5,8}, 3));
    }

    private static double getAverageOfAllKCombinations(int[] inputs, int k) {

        int n = inputs.length;
        long sum = 0;
        for (int i = 0; i < n; i++) {
            sum += inputs[i];
        }

        double output = 0;
        if (k >= n) {
            output = sum;
        } else if (k > 0) {
            double combinations = 1;
            double divider = 1;

            for (int i = n; i > k; i--) {
                combinations *= i;
            }
            for (int i = 2; i <= k; i++) {
                divider *= i;
            }
            combinations /= divider;

            double frequency = 1;
            for (int i = n - 1; i > k; i--) {
                frequency *= i;
            }
            divider = 1;
            for (int i = 2; i < k; i++) {
                divider *= i;
            }
            frequency /= divider;

            output = sum * frequency / combinations;
        }
        return output;
    }

}

Plz纠正我,如果错了。