我想要一个解决以下问题的有效算法的提示:
(好吧,问题不是那个,我只是为了简单起见)
示例:在 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;
}
?>
答案 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))时间内运行