我的作业包括动态编程问题:
给出两个自然整数数组(a1,a2,...,an和b1,b2,...,bn) 所有这些都小于n ^ 2,并且还给出了数字B. 小于n ^ 3。
你需要阻止是否有一个数组(c1,c2,...,cn):
对于每个1< = i< = n,ci = ai或ci = bi。
*此算法必须使用动态编程编写。
*另外,我们需要改变什么来实际获得给出Sum(c)= B
的数组c
另一种看问题的方法是说c等于a的子集,而b的补充子集等于。
这是我为解决这个问题而编写的递归伪代码:
W(a,b,i, N)
if i==-1
if N==0 return true;
else return false;
return W(a,b,i-1,N-a[i]) || W(a,b,i-1,N-b[i]);
T(n) = 2^n
在这里,要返回最佳路径,只需将其存储在树中,然后从(好)端转到开头
如何使用动态编程来编写?这甚至可以帮助运行时间吗?因为递归解决方案具有独立的结果。
*我搜索谷歌这个问题,但发现了“子集总和问题”,这是不同的。
答案 0 :(得分:1)
感谢@PhamTrung,我有一个解决方案:
让矩阵[B,n](最大尺寸[n ^ 3,n])
示例:(n = 3,B = 8)
0 1 2 3 4 ... 8
0 T F F F F ... F
1 F (1,1) (1,2) (1,3) (1,4) ... (1,8)
2 F F (2,2) (2,3) (2,4) ... (2,8)
3 F F F (3,3) (3,4) ... (3,8)
伪代码:
//Generate the matrix
A = new Array(n+1,B+1)
for(i: 0 to n) //run over lines
for(j: 0 to B) //run over B columns
if i==0 //if we are in the first row
A[i,j] = j==0; //if this is [0,0], it is true. else, false
else if i>j //if we have more numbers than the sum
A[i,j] = false; //it cannot happen
else
//general case:
//if we remove a[i] or b[i], will we get to a true statement?
A[i,j] = (j-a[i] >= 0 && A[i-1, j-a[i]]) || (j-b[i] >= 0 && A[i-1, j-b[i]]);
is_set(n,B,A)
if(A[n,B])
return true;
return false;
公式:
[0,j],j!=0 = F
[0,0] = T
i > j = F
i <= j = (i-1, j - a[i]) || (i-1, j - b[i])
获取路线:
要获得构建C的路径,我们还将保存每个真实点0(= a)或1(= b),并从底部到顶部。