アルゴリズム毎週質問005:カットスティック

問題:

仮定するcmの長さnは、長さ1cmの小片に切断守らなければならないが、唯一のスティックは、セクション3に切断される人スティックおよびセグメンテーションによって3人によって同時にスライスしますスティック。m個の個々の最大値を求める際に、少なくとも数回カットします。

例えば、N = 8、M = 3以下に示すように、その上に4倍を切りました。
アルゴリズム毎週質問005:カットスティック

セグメンテーションのN = 20、M = 3の最小数を求める場合。
N = 100で求めたとき、mは5回分割の最小値を=。

アイデア:

この質問は、最も難しいのアルゴリズムではなく、問題を理解します。
最初だけスティックでは、タイトルの規定二つに分割した後一人で、今回「1本のスティックは、スライスされた1人だけだった」;
2スティックとセグメンテーションを行う、私たちは満たす必要がある「1。唯一のスティックとセグメンテーション者によって1「ルール、4に二人の個人、それぞれカットすることにより、この場合のように、
その後、トピックことを」スティックはセクション3に切断された場合であってもよく、同時に3人は、つまり、サブスティック」でカットされた
数は、スティックの上限数、彼らは唯一の人々の数の数の上限の分離を切ることができるたびに達したとき。
これに先立ち、十分な人々がそれぞれのスティック、毎回カットがあり、インクリメントされた棒の数を2倍に、二つに分割され、

で記述するために言葉を使用します。

スティックの現在の数> =上限回数、元の数+ =新しい木製スティック制限数の数、
スティック<上限数の現在の数、新しい木製スティック* = 2の元の数の数、
ときに、新しいスティック数は、スティックの長さ、スライスの終わりに等しいより大きい場合。

この問題は、再帰的にすることができ、サイクリングを解決するには、2つの方法があります。

再帰:

再帰終了条件は、現在の(スティックの現在の数)> = N(スティックの長さ)です。
場合<(スティックの現在数)現在のとき、M(最大数)=現在の電流2 *。
M + =現在の電流電流(スティックの現在の数)> = M(最大数)の時間は、ときに、
各再帰で、現在の再帰渡されたパラメータの数で付着する終了条件が満たされるまで。

ループ:

再帰ループ終了条件、また場合出射電流(スティックの現在の数)> = N(スティックの長さ)など、それが現在の<サイクルN行われているです。
場合<(スティックの現在数)現在のとき、M(最大数)、電流=電流+電流。
場合M + =現在の電流電流(スティックの現在の数)> = M(最大数)時間;
ループを通るたびに、カウント(サイクル数、即ち切断点の数)+1。

回答:

PHP

// 递归
// m 为上限人数
// n 为木棒长度
// current 为当前木棒数量
function cutBar($m, $n, $current)
{
    if ($current >= $n) {
        return 0;
    } elseif ($current < $m) {
        return 1 + cutBar($m, $n, $current * 2);
    } else {
        return 1 + cutBar($m, $n, $current + $m);
    }
}

// 循环
function cutBar2($m, $n)
{
    $current = 1;// 初始木棒数
    $count = 0; // 切分计数
    while ($current < $n) {
        $current += $current < $m ? $current : $m;
        $count++;
    }
    return $count;
}

$rs = cutBar(3, 8, 1);
echo $rs."\n";

$rs = cutBar(3, 20, 1);
echo $rs."\n";

$rs = cutBar(5, 100, 1);
echo $rs."\n";

$rs = cutBar2(3, 8);
echo $rs."\n";

$rs = cutBar2(3, 20);
echo $rs."\n";

$rs = cutBar2(5, 100);
echo $rs."\n";

出力:

4
8
22
4
8
22

golang

package main

import "fmt"

func main() {
    rs := cutBar(3, 8, 1)
    fmt.Println(rs)

    rs = cutBar(3, 20, 1)
    fmt.Println(rs)

    rs = cutBar(5, 100, 1)
    fmt.Println(rs)

    rs = cutBar2(3, 8)
    fmt.Println(rs)

    rs = cutBar2(3, 20)
    fmt.Println(rs)

    rs = cutBar2(5, 100)
    fmt.Println(rs)
}

func cutBar(m, n, current int) int {
    if current >= n {
        return 0
    } else if current < m {
        return 1 + cutBar(m, n, current*2)
    } else {
        return 1 + cutBar(m, n, current+m)
    }
}

func cutBar2(m, n int) int {
    current := 1
    count := 0
    for current < n {
        if current < m {
            current += current
        } else {
            current += m
        }
        count++
    }
    return count
}

出力:

4
8
22
4
8
22

おすすめ

転載: blog.51cto.com/ustb80/2425825