当前位置: 首页 > 知识库问答 >
问题:

使用动态规划选择最接近对的算法

华欣荣
2023-03-14

我一直在努力解决教授给我的这个问题,但没有找到合适的解决方案。问题如下

问题:矩形电路板有两个平行的侧面,它们之间的宽度为W。板的上侧有m个端子,n个端子(n

(a) 证明在最优解中,任意两条线段都不会相交。

(b) 设计一个O(mn)动态规划算法来解决这个最小化问题。您需要定义子问题,显示归纳公式、初始条件和伪代码。你可以用d(i,j)来表示U[i]和L[j]之间的距离,1≤ 我≤ m、 1个≤ j≤ n、 (d(i,j)=)的计算可以省略。

我的方法:

对于上述问题,我的方法是首先制作一个矩阵d(i, j),其中i是底部的端子,j是顶部的端子。d(i, j)具有与任何两个电路的所有距离。然后遍历每一行,我会找到最小的距离并标记相应的终端。但我不确定如果顶部电路都在一侧的最右边,这是否有效。所以有人能给我提供更好的方法吗?

共有1个答案

卫嘉谊
2023-03-14

我写了一个使用记忆的递归动态编程解决方案,复杂度为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个endpoint,那么距离就会减少,因此给我们一个更好的解决方案

 类似资料:
  • 主要内容:动态规划算法的实际应用动态规划算法解决问题的过程和分治算法类似,也是先将问题拆分成多个简单的小问题,通过逐一解决这些小问题找到整个问题的答案。不同之处在于,分治算法拆分出的小问题之间是相互独立的,而动态规划算法拆分出的小问题之间相互关联,例如要想解决问题 A,必须先解决问题 B 和 C。 《贪心算法》一节中,给大家举过一个例子,假设有 1、7、10 这 3 种面值的纸币,每种纸币使用的数量不限,要求用尽可能少的纸币拼凑

  • 我目前正在学习动态编程,我无法解决这个问题。有人能给我一个算法吗?:考虑一个有向图G=(V,E),其中每个边都标有一个字母Sigma的字符,我们指定一个特殊的顶点s作为开始顶点,另一个f作为最后顶点。我们说G接受一个字符串a=a1a2。如果有一条从s到f的n条边的路径,其标号拼写为序列a。设计了一个O((V+E)n)动态规划算法来确定a是否被G接受。

  • 我正在为动态编程编写一些复习材料。我需要提出如何划分子问题,计算出基本情况,并提出递归公式。 给定 n 个正整数 a1,a2,...,an、一个数字 k 和一个目标 W,我们希望选择一个子集 T,其总和恰好是 k 个元素,其总和最接近 W。每个元素只能选择一次。定义一个具有 3 个参数的子问题(即 C[x,y,z] = ...)。 我只处理过几个动态编程示例,从未处理过定义子问题时需要3个参数的示

  • 问题内容: 这可能比我做的要容易,但是基本上我需要做的是选择列中具有最接近数字的行作为指定值。例如: 数据库中指定列中的3行的值列表:10、15、16 如果我指定我想要最接近14的行,它将选择15的行。 另外,如果有2+行相同的距离,则随机选择其中之一。 问题答案: 一种选择是遵循以下方式: 要选择随机记录,可以将其添加到子句中。这种方法的缺点是您不能从索引中得到任何好处,因为您必须对派生值进行排

  • 我试图为最长公共子序列写一个动态规划算法。返回应该是这个子序列的长度。但是我的算法总是返回0。我找不到错误。

  • 我正在处理一个类似于可以用动态编程算法解决的盒子堆叠问题的问题。我在SO上阅读了有关它的帖子,但是我很难理解DP方法,并希望对其工作原理进行一些解释。这是手头的问题: 给定X个物体,每个都有自己的重量“w”和强度“s”,你能把多少个叠在一起?一个物体只要不超过它的强度,就可以承受它自身的重量和它上面所有重量的总和。 我知道它有一个最优子结构,但是它的重叠子问题部分让我困惑。我试着创建一个递归树,看