这是我正在做的关于动态编程的一个小练习。我有以下功能:
我必须用两种方法(自上而下的记忆和自下而上)来编程这个函数。
这是我目前为自下而上所做的:
public static int functionBottomUp (int n){
int [] array = new int[n+1];
array[0] = 1;
for(int i = 1; i < array.length; i++){
if(i == 1)
array[i] = array[i - 1];
else {
for(int p = 0; p < i; p ++)
array[i] += array[p];
}
}
return array[n];
}
对于记忆:
public static int functionMemoization(int n){
int[] array = new int[n+1];
for(int i = 0; i < n; i++)
array[i] = 0;
return compute(array, n);
}
private static int compute(int[] array, int n){
int ans = 0;
if(array[n] > 0)
return array[n];
if(n == 0 || n == 1)
ans = 1;
else
for(int i = 0; i < n; i++)
ans += compute(array, i);
array[n] = ans;
return array[n];
}
我得到了正确的输出,但现在我正在努力计算两者的复杂性。
首先,复杂性是f(n)
因为2^n
拨打f(3)
电话7
和f(0)
拨打f(4)
电话15
(f(0)
我知道这不是正式的证明,但这只是为了给我一个想法)。
但现在我被困在计算这两个函数的复杂性上。
自下而上:
我会说复杂性是 O(n) (因为
for(int i = 1; i < array.length; i++)
)但是有这个内部循环for(int p = 0; p < i; p ++)
,我不知道这是否会改变复杂性。
记忆化:
显然这是一个最复杂的 O(n),因为第一个循环初始化了数组。但我不知道计算函数如何修改这种复杂性。
有人可以为我澄清一下吗?