我一直试图解决我教授给我的这个问题,但无法做出正确的解决方案。以下是问题
问题:
矩形电路板具有两个平行的侧面,它们之间具有宽度W.在板的上侧有m个端子,在下侧有n个端子(n
(a)证明在最佳解决方案中,任何两个线段都不会相交。
(b)设计一个O(mn)动态规划算法来解决这个最小化问题。您需要定义子问题,显示归纳公式,初始条件和伪代码。您可以使用d(i,j)表示U [i]和L [j]之间的距离,1≤i≤m,1≤j≤n。 (d(i,j)=)的计算可以省略。
我的方法:
对于上述问题,我的方法是首先制作一个矩阵d(i,j),其中i是底部的终端,j是顶部的终端。 d(i,j)具有距任意两个电路的所有距离。然后迭代每一行,我将找到最小距离并标记相应的终端。但我不确定如果顶部电路都在极右侧,这将会起作用。所以任何人都可以为我提供更好的方法。
答案 0 :(得分:1)
我编写了一个使用memoisation的递归动态编程解决方案,复杂度为O(mn),在每个递归级别,我们可以选择加入U []数组中定义的当前点和在L []数组,或者我们可以继续前进而不这样做:
#include<iostream>
#define INF 1e9
using namespace std;
int n, m, d[100][100], dp[100][100];
int solve(int idx1, int idx2){
if(idx1 > m){
if(idx2 < n) return INF;
else return 0;
}
if(idx2 > n) return 0;
if(dp[idx1][idx2] != -1) return dp[idx1][idx2];
int v1, v2;
//include current
v1 = solve(idx1 + 1, idx2 + 1) + d[idx1][idx2];
//do not include current
v2 = solve(idx1 + 1, idx2);
return dp[idx1][idx2] = min(v1, v2);
}
int main(){
//enter the the distances
for(int i = 0;i < 100;i++) for(int j = 0;j < 100;j++) dp[i][j] = -1;
cout << solve(1, 1) << endl;
return 0;
}
对于你问题的(a)部分,让我们假设2个线段相交,那么我们就不能有最优解,因为如果我们只交换L []数组定义的线段的2个端点然后距离会减少,从而为我们提供更好的解决方案。