簡體   English   中英

動態規划求解算法

[英]Dynamic Programming solving an algorithm

使用動態規划方法為定義的函數H計算值H(7) ,以使H(1)= 2,H(2)= 3,並且對於所有整數i> 2 ,我們具有: H(i)= H( i-2)-H(i-1)+2。

我查了一下,看了一些視頻,並閱讀了有關動態編程的文章。 但仍在與上述問題作斗爭。 我了解您可以通過預先解決較小的問題來解決主要問題。 這樣您就有更多的機會解決主要問題,因為您可以參考以前的創建。 您已經找到的這些先前結果已傳遞到結果中,但這是我無法解決的問題。

H(1)= H(1-2)-H(1-1)+2。
H(2)= H(2-2)-H(2-1)+2。
H(3)= H(3-2)-H(3-1)+2。
H(4)= H(4-2)-H(4-1)+2。
H(5)= H(5-2)-H(5-1)+2。
H(6)= H(6-2)-H(6-1)+2。

我假設應該將這些的簡單計算放到一個表中,然后以某種方式應該使用此信息來算出H(7)

我是完全錯誤的主意還是正確地做,我不知道= [這也是決賽的修訂。

您的任務類似於fibonnaci :)首先,我將向您解釋fibonacci。

F(1)= 1
F(2)= 1
對於每個N> 2,F(N)= F(N-1)+ F(N-2)

前幾個斐波那契數字:
F(1)= 1
F(2)= 1
F(3)= F(2)+ F(1)= 2
F(4)= F(3)+ F(2)= 3
F(5)= F(4)+ F(3)= 5
...

您可以在以下網站上看到更多信息: http : //en.wikipedia.org/wiki/Fibonacci_number

斐波那契數的斐波那契數列由遞歸關系定義。 斐波那契序列是遞歸序列。

每次遞歸必須具有:
1)基本案例
2)遞歸關系

在斐波那契的情況下,基本情況為: F(1)等於1F(2)也等於1 遞歸關系是“連接”同一問題的較小實例的關系。 對於斐波那契數,如果您想知道F(N) ,那么對於所有N> 2 ,您都必須知道F(N-1)F(N-2),僅此而已。 在斐波那契的情況下,遞歸關系為F(N)= F(N-1)+ F(N-2)

這是代碼:

#include <cstdio>
#include <cstdlib>

using namespace std;

int f(int n) {

    //printf("n = %d\n", n);
    if(n == 1 || n == 2) // base case
        return 1;
    return f(n - 1) + f(n - 2); // recurrence relation

}

int main() {

    int n; scanf("%d", &n);
    printf("%d\n", f(n));

    return 0;
}

如果刪除帶有注釋的printf,您將看到許多斐波那契值被一遍又一遍地計算,這是非常低效的。 嘗試為F(45)運行此代碼,您將明白為什么它效率很低。

這就是動態編程的地方。您可以看到,許多斐波那契值是一遍又一遍地計算的,我們可以使用記憶將它們保存在表中,如果需要,我們可以從表中返回它們。 這是代碼:

#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;
const int N = 50;

long long memo[N];

long long f(int n) {
    if(memo[n] != -1) // if we already computed the value of f(N), then return that value
        return memo[n];
    return memo[n] = f(n - 1) + f(n - 2); // else compute the value, and save it into the table
}

int main() {

    memset(memo, -1, sizeof(memo));

    memo[1] = memo[2] = 1; // add answer for base case to the table

    int n; scanf("%d", &n);
    printf("%lld\n", f(n));

    return 0;
}

最后,你的問題。

作為斐波那契,您可以保存h(N)的計算值。 這是一個代碼:

#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;
const int N = 25;

int check, memo[N];

int f(int x) {
    if(memo[x] != check) // if f(n) was already computed
        return memo[x]; // return computed value
    return memo[x] = f(x - 2) - f(x - 1) + 2; // else compte given value and add it to a table
}

int main() {

    memset(memo, 63, sizeof(memo)); // very big number, if the value of h(n) is different then that very big number, then we know we have computed the value for h(n)
    check = memo[0];

    memo[1] = 2; // base case
    memo[2] = 3; // base case

    int n; scanf("%d", &n);
    printf("%d\n", f(n));

    return 0;
}

給你

H(1)=2
H(2)=3

根據該信息以及H(i)的公式,您可以如下計算H(3)

H(3) = H(3-2) - H(3-1) + 2 = H(1) - H(2) + 2 = 2 - 3 + 2 = 1

沖洗並重復。

高(1)= 2
高(2)= 3
H(3)= H(1)-H(2)+ 2 = 2-3 + 2 = 1
H(4)= H(2)-H(3)+ 2 = 3-1 + 2 = 4
H(5)= H(3)-H(4)+ 2 = 1-4 + 2 = -1
H(6)= H(4)-H(5)+ 2 = 4-(-1)+ 2 = 7
H(7)= H(5)-H(6)+ 2 = -1-7 + 2 = -6
所以H(7)是-6

在瀏覽器中打開JavaScript控制台,然后輸入:

function H(i) { return i==1 ? 2 : i==2 ? 3 : H(i-2)-H(i-1)+2 }

然后

H(7)

哪個返回

-6

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM