给你一个矩阵A,代表一个有N行M列的棋盘。棋盘的每一个方格都包含一个整数,代表一个基于点数的分数。你必须把两辆车放在棋盘上,这样它们就不能互相攻击,而且它们的方格上的点数之和是最大的。国际象棋中的车只有在同一行或同一列时才能互相攻击。
例如,给定下图中的矩阵:
我们可以用两种不同的方式来放置车
- 一辆车在A[00][00] = 1,另一辆车在A[01][02] = 3。这些正方形上的点数之和是4。
- 一辆车在A[00][02] = 4,另一辆车在A[01][00] = 2。这些正方形上的点数之和是6。你的任务是找到两个可以放置车的棋盘格的最大和。在上面的例子中,答案是6。例如,我们不能把车放在A[00][02]和A[01][02](它们的和是7),因为它们会互相攻击。
写一个函数:函数解(A);给定矩阵A,返回放置两个非攻击车所能达到的最大和
示例:
1.给定两行两列的矩阵A:
函数返回6。我们可以通过选择A[00][02] + A[01][00] = 4 + 2来实现最大和。选定的方块以绿色标记
1.给定一个三行三列的矩阵A:
函数返回23。我们可以通过选择A[00][00] + A[01][02] = 15 + 8来实现最大和。选定的方块以绿色标记。
1.给定三行两列的矩阵A:
该函数将返回24。我们可以通过选择A[00][00] + A[01][02] = 12 + 12或A[00][02] + A[01][00] = 12 + 12来实现最大和。后者溶液用绿色标记。
1.给定两行三列的矩阵A:
该函数将返回22。我们可以通过选择A[00][02] + A[01][00] = 14 + 8来实现最大和。选定的方块以绿色标记。为下列假设编写一个有效的算法
N和M是在**[2..600]范围内的整数;矩阵A的每个元素是范围[0..1,000,000,000]**内的整数。
我试过了,但不认为这是有效的。
function solution(A) {
const N = A.length;
const M = A[0].length;
let maxSum = 0;
if(N > M){
for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
for (let col1 = 0; col1 < M; col1++) {
for (let col2 = col1 + 1; col2 < M; col2++) {
if (col1 !== col2) {
const sum = A[i][col1] + A[j][col2];
maxSum = Math.max(maxSum, sum);
}
}
}
}
}
return maxSum;
}
for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
for (let col1 = 0; col1 < M; col1++) {
for (let col2 = 0; col2 < M; col2++) {
if (col1 !== col2 && A[i][col1] !== A[j][col2]) {
maxSum = Math.max(maxSum, A[i][col1] + A[j][col2]);
}
}
}
}
}
return maxSum;
}
2条答案
按热度按时间yks3o0rb1#
你可以在线性时间内解决这个问题。
只需逐行遍历矩阵,然后:
\
。/
这样的车排列。1dkrff032#
我们可以很容易地在一个函数的基础上构建这个函数,该函数创建一个网格,删除与给定正方形共享一行或一列的所有单元格。该函数反过来可以写在从数组中删除给定索引的函数之上。它可能看起来像这样:
我们的主函数首先确保我们甚至可以得到两个非攻击车,这意味着我们至少有两行至少两列。如果不是,我们返回
-Infinity
作为信号。否则,我们会找到两个值的最大值:首先,我们跳过初始行,并在剩余的行上重复。其次,我们在第一行中测试每个值,删除相关的行和列,并找到最大的剩余正方形并将其添加到我们的单元格值中。这两个值的最大值是我们能做的最好的。请注意,这种技术可以很容易地扩展到找到网格中 * 所有 * 非攻击车的最大总和,只需循环而不是扁平化并在第二个主分支中取最大值。(我知道,因为这是我第一次写关于误读问题的文章;这里介绍的版本只是稍微简单一点)。