int s_dynamic(int n,int k) {
int maxj = n-k;
int *arr = new int[maxj+1];
for (int i = 0; i <= maxj; ++i)
arr[i] = 1;
for (int i = 1; i <= k; ++i)
for(int j = 1; j <= maxj; ++j)
arr[j] += i*arr[j-1];
return arr[maxj];
}
这是我尝试使用动态编程确定斯特林数字。
定义如下:
好吧,好吧?除非我进行单元测试...S(n,k)= S(n-1,k-1)+ k S(n-1,k),如果1 <1。 k&lt; n
S(n,k)= 1,如果k = 1 ou k = n
partitioningTest ..\src\Test.cpp:44 3025 == s_dynamic(9,3) expected: 3025 but was: 4414
谁能看到我做错了什么?
谢谢!
顺便说一下,这是递归解决方案:int s_recursive(int n,int k) {
if (k == 1 || k == n)
return 1;
return s_recursive(n-1,k-1) + k*s_recursive(n-1,k);
}
答案 0 :(得分:4)
发现错误。 您已经计算了k = 1的斯特林数的动态数组(对于所有n,S(n,1)= 1)。 你应该开始计算S(n,2) - 即:
for (int i = 2; i <= k; ++i) //i=2, not 1
for(int j = 1; j <= maxj; ++j)
arr[j] += i*arr[j-1];
答案 1 :(得分:3)
你的方法很好,除了你似乎做了一个简单的索引错误。如果您考虑i
和j
所代表的索引以及内循环将arr[j]
转换为什么,您会看到它很容易(我撒谎,我花了半个小时弄清楚是什么:))。
根据我可以解码的内容,i
代表计算期间的值k
,arr[j]
从S(i+j, i-1)
转换为S(i+1+j, i)
。初始化arr
的最顶层for循环将其设置为S(1+j, 1)
。根据这些循环,计算看起来很好。除了一件事:第一个i
循环假设arr[j]
包含S(0+j, 0)
,因此它就是您的问题所在。如果您将i
的起始值从1
更改为2
,则所有内容都应该正常(您可能需要if或者两个边缘情况)。最初的i=2
会将arr[j]
从S(1+j, 1)
转换为S(2+j, 2)
,其他转换将会很好。
或者,您可以将arr[j]
初始化为S(0+j, 0)
(如果已定义),但不幸的是,斯特林的数字在k=0
未定义。
i
的起始值保留为1
。为此,您可以使用初始值S(0, 0)=1
和S(n, 0)=0, n>0
。