質問

していただくことになります。私は飛者のう仕事を通じてSICP(なんと無料です! あの例の手続きの第一章には、そのカウントの方法を変更とアメリカ貨;(メーカー100)=>292.この実装のようなもの:

(define (change-maker amount)
  (define (coin-value n)
    (cond ((= n 1) 1)
          ((= n 2) 5)
          ((= n 3) 10)
          ((= n 4) 25)
          ((= n 5) 50)))

  (define (iter amount coin-type)
    (cond ((= amount 0) 1)
          ((or (= coin-type 0) (< amount 0)) 0)
          (else (+ (iter amount
                         (- coin-type 1))
                   (iter (- amount (coin-value coin-type))
                         coin-type)))))

  (iter amount 5))

とにかく;このツリーの再帰の手順は、著"葉として用いられてきましたが、"探す、繰り返しの手続きを同じ問題(ie固定していく予定である。っていないのが運のコーヒーに飽きたら寿司にこのやることでその問いしよう。った場合で脳おなら私の場合、または作成者のねじ込みください。

役に立ちましたか?

解決

最も簡単な/最も一般道を再帰一般的に、補助スタック--その代わりに、再帰呼び出し、押しその引数をスタックに対して繰り返し処理を実行.が必要な場合に、結果の再帰呼出しを進めるために、さらに一般の場合ことになるtadより複雑なもんもんてきした後、"継続請求"(の補助スタックの結果が知られる);しかし、この場合には、すべてやっているすべての再帰呼出しの結果は合計でないアキュムレータに、毎時を取得します結果ではなく、さらに取り組む必要があり、追加でに蓄積する。

しかし、これ自体は ない 固定スペース、スタック伸びます。でももう:これは純粋な機能(副作用はありませんし、時間のみを計算関数の値を一定の議論でき memoize 引数の結果対応となります。この数を制限されます。別のコンセプチャルなアプローチにつながるものと同じ計算する 動的計画 [[通称DP]]がDPのとおり作業のボトムアップ"の結果の準備をするmemoized"についてのよりはじめ、再帰を排除します。

取り下DPこの機能です。きを繰り返しで終わるのか"を多くの方々に変化量Xの最小コイン"としてまwhittleもともと物事をX様々なコインの組み合わせの原 amountる必要はありません。開始算出者 amount 値の単純な繰り返し処理(f(X)= X/value の場合 X がで割り切れる最小-コイン価値 value, かっ 0;ここで、 value 1、f(X)=XすべてのX>0)です。ま続きを計算することにより、新しい関数g(X)方法の変更のためのXとの 二つの 最小コイン:も単純な繰り返し増X g(x)=f(X)+g(X- valuevalue 第最小コインさせていただきます(単純な繰り返し処理での時間だけ計算g(X)すでにみんな計算れf(X) すべてのg(Y)Y < Xのコースg(X)=0X <=0)です。まh(X)方法の変更のためのXとの 最小コインh(X)=g(X)+g(X-value①ある製品について、やらなf(X)のように再利用することも可能で その スペース。すべての彼が、これに必要なスペース 2 * amount --な"固定スペース"なのですが、近づいてい...

最終的には飛躍"固定スペース"は、自分自身に尋ね:いを続けるために必要な周辺 すべての 値の配列の各ステップの一つで計算され、一つだけコンピューティング、または、 一部の の価値を組み替えることによってごループを味---?

他のヒント

私が思いついた解決策は、

「財布」を使用しているコインの種類ごとの数を維持することです

メインループは、このように動作します。変更「denomは、現在の宗派である」「与えられた私は確認する必要があり、変更の量れる」、クリアアップには財布の外に与えられた額面金額よりも小さい全てのコインを取る財布硬貨の合計値でありますます。

#lang scheme
(define (sub changed denom)
  (cond
   ((> denom largest-denom)
    combinations)

   ((>= changed given)
    (inc-combinations-if (= changed given))

    (clear-up-to denom)
    (jump-duplicates changed denom)) ;checks that clear-up-to had any effect.

   (else
    (add-to-purse denom)
    (sub
     (purse-value)
     0
     ))))

(define (jump-duplicates changed denom)
  (define (iter peek denom)
    (cond
     ((> (+ denom 1) largest-denom)
      combinations)

     ((= peek changed)
      (begin
        (clear-up-to (+ denom 1))
        (iter (purse-value) (+ denom 1))))

      (else
       (sub peek (+ denom 1)))))
  (iter (purse-value) denom))

アレックスマルテッリの答えを読んだ後、私は財布のアイデアを思い付いたが、ちょうどそれが動作することに暇

ここの動的なプログラミングを使用して、機能の私のバージョンであります。サイズN + 1のベクトルは、0番目の項目は、k番目から始まる各可能なコイン(外側のループを行う)、各ベクトル要素(内側ループを実行し)、次いで、最初は1であることを除いて、0に初期化されますkは、コインの値であり、現在のインデックスマイナスkにおける値だけインクリメントされる。

(define (counts xs n)
  (let ((cs (make-vector (+ n 1) 0)))
    (vector-set! cs 0 1)
    (do ((xs xs (cdr xs)))
        ((null? xs) (vector-ref cs n))
      (do ((x (car xs) (+ x 1))) ((< n x))
        (vector-set! cs x (+ (vector-ref cs x)
          (vector-ref cs (- x (car xs)))))))))

> (counts '(1 5 10 25 50) 100)
292

あなたは http://ideone.com/EiOVY の時にこのプログラムを実行することができます。

だから、このスレッドの中で、質問の元アスカーは音の答えを思い付きますモジュール化を介しました。あなたはcc-penniesが完全に不必要であることに気づく(ひいては、そのcc-nothingがある)場合、私は彼のコードを容易に最適化することができ、しかし、お勧めします。

を参照してください、cc-penniesが書かれている方法に問題はどこへ行くか全く下宗派がありませんので、それは高い金種手続きの構造を模倣することにより行いますすべては(- amount 1)する0から降りて反復され、それがこれを行うだろう、ということですたびに、あなたはそれcc-nickels手順の量渡します。あなたが1ドルを試すのであれば、最初のパスで、あなたは100のamountを取得しますので、(- amount 1)はあなたが99cc-penniesサイクルの99回の余分のサイクルを受けるだろうことを意味する、cc-nothingして評価します。その後、硬貨はそうでなど、あなたが94回の以上無駄なサイクルを取得するので、あなたは、量として95渡します。あなたも、ダイム、または四半期、または半ドルにツリーを上に移動する前に、それがすべてです。

あなたがcc-penniesてもらう時点で、あなたはすでにあなただけの1でアキュムレータアップしたい知っているので、私はこの改善をお勧めます:

(define (count-change-iter amount)
    (cc-fifties amount 0))

(define (cc-fifties amount acc)
    (cond ((= amount 0) (+ 1 acc))
        ((< amount 0) acc)
        (else (cc-fifties (- amount 50)
                (cc-quarters amount acc)))))

(define (cc-quarters amount acc)
    (cond ((= amount 0) (+ 1 acc))
        ((< amount 0) acc)
        (else (cc-quarters (- amount 25)
                (cc-dimes amount acc)))))

(define (cc-dimes amount acc)
    (cond ((= amount 0) (+ 1 acc))
        ((< amount 0) acc)
        (else (cc-dimes (- amount 10)
                (cc-nickels amount acc)))))

(define (cc-nickels amount acc)
    (cond ((= amount 0) (+ 1 acc))
        ((< amount 0) acc)
        (else (cc-nickels (- amount 5)
                (cc-pennies amount acc)))))

(define (cc-pennies amount acc)
    (+ acc 1))

あなたはこれが有用であることが判明願っています。

あなたは擬似多項式時間で動的なプログラミングを繰り返し、それを解決することができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top