[英]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)等於1和F(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.