抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

扣分后的最大得分

题目

给你一个 m x n 的整数矩阵 points (下标从 0 开始)。一开始你的得分为 0 ,你想最大化从矩阵中得到的分数。

你的得分方式为:每一行 中选取一个格子,选中坐标为 (r, c) 的格子会给你的总得分 增加 points[r][c] 。

然而,相邻行之间被选中的格子如果隔得太远,你会失去一些得分。对于相邻行 r 和 r + 1 (其中 0 <= r < m - 1),选中坐标为 (r, c1) 和 (r + 1, c2) 的格子,你的总得分 减少 abs(c1 - c2) 。

请你返回你能得到的 最大 得分。

abs(x) 定义为:

  • 如果 x >= 0 ,那么值为 x 。
  • 如果 x < 0 ,那么值为 -x 。

思路

  • 回溯
  • 动态规划
  • 动态规划优化

选择问题一般都可以用回溯的思路进行解决,但是回溯的时间复杂度很大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
int res = 0;
public long maxPoints(int[][] points) {
dfs(points,0,0,0);
return res;
}
public void dfs(int[][] points,int row, int col, int score){
if (row >= points.length) {
res = Math.max(res,score);
return;
}
for (int i = 0; i < points[row].length; i++) {
int newScore = score + points[row][i];
if (row > 0){
newScore -= Math.abs(col - i);
}
dfs(points,row+1,i,newScore);
}
}
}

动态规划解法
dp[i][j] 代表i行j列的最大得分

状态转移方程:
dp[i][j] = max{ dp[i-1][k] + points[i][j] + abs(j-k) ,k = 0-n n为points列长度}
时间复杂度?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public long maxPoints(int[][] points) {

if (points.length == 0) {
return 0;
}
long result = 0;
int m = points.length;
int n = points[0].length;
long[][] dp = new long[m][n];
for (int i = 0; i < n; i++) {
dp[0][i] = points[0][i];
result = Math.max(result,dp[0][i]);
}
for (int i = 1; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
long score = points[i][j] + dp[i-1][k] - Math.abs(j-k);
dp[i][j] = Math.max(score,dp[i][j]);
}
result = Math.max(result,dp[i][j]);
}

}
return result;

}

}

动态规划优化解法

1
2


评论