LCP 57. 打地鼠
思路:从最后一个出现位置进行往前递推。
f
[
i
]
[
x
]
[
y
]
记
录
第
i
次
出
现
时
位
置
的
(
x
,
y
)
能
打
老
鼠
到
的
个
数
f[i][x][y]记录第i次出现时位置的(x,y)能打老鼠到的个数
f[i][x][y]记录第i次出现时位置的(x,y)能打老鼠到的个数
利用当前时间和上个时间的差值diff,进行判断能否转移
a
b
s
(
x
i
−
x
i
+
1
)
+
a
b
s
(
y
i
−
y
i
+
1
)
<
=
d
i
f
f
abs(x_i - x_{i+1}) + abs(y_{i} - y_{i+1}) <= diff
abs(xi−xi+1)+abs(yi−yi+1)<=diff
将上一个位置的各个位置的count 转移到 当前位置 。
再在当前 老鼠出现位置的 能打到个数 + 1;
最后转移从第0个老鼠出现 到 初始位置的
class Solution {
static int N = (int) 1e5 + 10;
static int f[][][];
;
static boolean vis[][];
public int getMaximumNumber(int[][] moles) {
int n = moles.length;
f = new int[N][3][3];
Arrays.sort(moles, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});
// for (int i = 0; i < n; i++) {
// System.out.println(Arrays.toString(moles[i]));
// }
// int x = moles[n-1][moles[n-1][1]];
// int y = moles[n-1][moles[n-1][1]];
f[n][moles[n-1][1]][moles[n-1][2]]=1;
for (int i = n - 1; i >= 1; i--) {
int nx = moles[i - 1][1];
int ny = moles[i - 1][2];
// 从每个点开始转移
int diff = moles[i][0] - moles[i-1][0];
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
for (int xx = 0 ; xx <3 ; xx++){
for(int yy = 0 ; yy < 3 ;yy++){
if(diff >= Math.abs(xx-x) + Math.abs(yy-y)) f[i][x][y] = Math.max(f[i][x][y],f[i+1][xx][yy]); // 转移上一个状态
}
}
}
}
f[i][nx][ny]++;
}
for (int xx = 0 ; xx <3 ; xx++){
for(int yy = 0 ; yy < 3 ;yy++){
if(moles[1][0] >= Math.abs(xx-1) + Math.abs(yy-1)) f[0][1][1] = Math.max(f[0][1][1],f[1][xx][yy]); // 转移第零个老鼠到 初始位置
}
}
return f[0][1][1];
}
// 第一次用dfs 转移 一直wa。。也没找到哪错了
public void transer(int t, int x, int y, int idx, int ox, int oy) { // 转移 ‘
if (x < 0 || y < 0 || y >= 3 || x >= 3 || t < 0 || vis[x][y]) {
return;
}
f[idx][x][y] = Math.max(f[idx][x][y], f[idx + 1][ox][oy]);
vis[x][y] = true;
transer(t - 1, x - 1, y, idx, ox, oy);
transer(t - 1, x, y - 1, idx, ox, oy);
transer(t - 1, x + 1, y, idx, ox, oy);
transer(t - 1, x, y + 1, idx, ox, oy);
}
}