从N个项目中选择最小项目,使得K个连续项目中应该有M个项目

时间:2013-05-22 18:35:46

标签: php math combinations combinatorics

我想要一个解决以下问题的有效算法的提示: (好吧,问题不是那个,我只是为了简单起见) 示例:在 N 广告板中, K 连续板中的公司应该有 M 广告。广告的使用方式只会使用 MINIMUM 个广告数量
如果N = 3,则K = 2,M = 1。答案是一个010;
如果N = 6,K = 3,M = 2,则答案为6.
011011, 011101, 011110, 101101, 101110 110110.

我采用了迭代和递归方法创建所有组合(使用二进制方法)的方法。之后我对其进行了过滤。它运作良好,除非N很大,它会崩溃。(正如预期的那样)。那么有没有有效的解决方法呢?

我只是采取了另一种方法,但它不会很好...... :(

第二种方法

if($n%$k == 0){
$perm = $m*($n/$k);
}else{
$perm = $m*ceil($n/$k);
}
Then I will do the nCr... and now I'm lost

第一种方法

<?php
$n = $input1;$k = $input2;$l=$input3; $total = 0;
$flag = false;$arrays = array();$z=0;$min=$n;$x=0;

$total_permutations = pow(2,$n);
for($i=0;$i<$total_permutations;$i++){
    $binary = base_convert($i, 10, 2);
    $binary = str_pad($binary, $n,"0", STR_PAD_LEFT);
        for($j=0;$j<=($n-$k);$j++){
            $flag = false;$x=0;
                for($m=0;$m<$k;$m++){
                    $x += intval($binary{$j+$m});
                }
            if($x<$l){
                $flag = true;
                break;
            }
        }
    if(!$flag){
        $arrays[$z]=str_split($binary);
        $arrays[$z] = array_map('intval', $arrays[$z]);
        $z++;
    echo $binary."<br />";
    }
    unset($binary);
}
$min = min(array_map('array_sum',$arrays));
echo "------------<br />";
foreach($arrays as $val){
    $sum = array_sum($val);
    if($sum == $min){
        echo implode("",$val);echo "<br>";
        $total++;
    }
}
return $total;

}
?>

1 个答案:

答案 0 :(得分:1)

详细说明我的评论,这是一个可能的解决方案(尽管如果没有更好的解决方案,我会非常失望)

1)首先,计算有效解决方案中所需的最小1的数量。 (我相信这只是max(M, floor(n/k)*m + max(0, n%k-(k-m)))。公式来源于一次构建一个字母的字符串,尽可能放置0)

2)现在,假设N> K(否则答案是微不足道的)。 我们将子问题定义为:“给定长度为K的前缀P,以及要放置1的预算B,在执行M规则的同时填写N个字符的方式有多少?”

例如,考虑我们的字符串是“101XXXXXX”,其中K = 3,M = 2,B = 4.这里,N = 6,P =“101”。我们像这样解决这个子问题:

a) Check if the budget is big enough in O(N) time.  Return 0 if it isn't
   If N=0, return 1 trivially
b) Set total possible solutions to 0
c) Set the first unknown character to 1.  Compute the new prefix P'
   (by stripping off the first character, and adding a "1" to the end),
   the new B' = B-1, the new N' = N-1, and solve the new sub-problem:
     Add its result to our total
d) Set the unknown character to 0 instead:  But only if the new prefix P'  
  (strip, add "0") has at least M 1's.  If so, set B' = B-1, N' = N-1,  
  and solve the new sub-problem.  Add its result to our total
e) Return the total

要解决原始问题,只需考虑所有可能的前缀P(它们的所有nCr(K,M)),并总结导出的子问题的解决方案。通过基于唯一输入P,N和B将结果缓存到子问题,我们大大减少了重复工作量。摊销分析应显示完整解决方案在O(N * nCr(K,M))时间内运行