“好”数的算法

时间:2013-07-19 00:05:32

标签: php algorithm big-o dynamic-programming pseudocode

如果数字x的任何两个连续数字的总和在k和2k之间,则给定数字x是“好”。 我需要找到一个算法,对于给定的数字k和给定的数字n,找到有多少'好'的n位数字。

我在PHP中实现了这个,但复杂性很大(我正在搜索所有那些'好'的数字并计算它们,因此复杂度为O(10 ^ n))。

<?php
    $n = 5;
    $k = 5;

    $min = $k*1;
    $max = $k*2;
    $counter = 0;

    for ($i = pow(10, $n-1); $i<pow(10,$n); $i++)
    {
        $number = $i;
        $prev = $number % 10;
        $number = $number / 10;

        while($number >= 10)
        {
            $crnt = $number % 10;
            $number = $number / 10;
            if ( ($crnt+$prev) > $min AND ($crnt+$prev) < $max ) {
                echo "good number: $i\n";
                $counter++;
            }
            $prev = $crnt;
        }
    }

    echo "counter: ".$counter."\n";
?>

有人可以确认我是否可以解决这个问题:

n=100 // given
k=10  // given

counter = 0;

for(i=10; i<100; i++)
{
    if( (i/10)+(i%10) > k ) && ( (i/10)+(i%10) < 2*k )
        counter++;
}

total = counter^(n-1)

3 个答案:

答案 0 :(得分:2)

pow的所有电话肯定都没有帮助。

您可以做的是对所有“好”的两位数字进行映射。完成映射后,您需要做的就是检查数字中的每对数字是否正常。您可以通过连续除以10和模100来完成此操作。

这样的事情可以解决问题,前提是你没有给它一个负数,假设你已经设置了$good数组。

function isgood( $num ) {
    while( $num >= 100 && $good[$num%100] ) {
        $num /= 10;
    }
    return $good[$num%100];
}

下一个最明显的事情是记住更大的序列。这是一种动态编程原理。我们已经通过存储2位序列的“优点”来记忆小序列。但你可以很容易地使用它们来生成3,4,5,6位的序列...无论你的可用内存允许什么。使用您已有的备忘录来生成一个额外数字的序列。

因此,如果您为最多5位数字建立了备忘录,那么每次除以1000,并获得极大的加速。

答案 1 :(得分:1)

查找n位数和最高位数d的“不好数字”的数量是一个简单的动态编程问题。

10^n是“好数字”加上“不好数字”的数量。

我不会给你更多的帮助。

答案 2 :(得分:0)

您的算法计算 NOT 良好的2位数整数。然后它将此值返回到n - 1的幂。这应该可以得到不好的n个数字。如果从n数字整数的总量中减去此值,您应该得到您想要的结果。或者我们可以通过改变标志来避免这样做:

for($i=10; $i<100; $i++) {
 if( ($i/10) + ($i%10) > $k && ($i/10) + ($i%10) < 2*$k ) {
  $cnt++;
 }
}
$result = pow($cnt, $n-1);

这应该可以得到好的n数字整数,但让我们看看是否真的如此。

好吧,cnt会给出好2位整数的数量。因此,在前两个位置,我们可以放置cnt中的任何一个:

0 1 2 3 4 5 ...
x y

那么,第1和第2位呢?那么,位置1由第一个位置固定。

0 1 2 3 4 5 ...
x y
  y z

所以我们必须证明cntz种可能性,我不明白为什么会出现这种情况,所以我会说算法错了。你的算法可能会超额计算。