1 import java.io.*;
2 import java.util.*;
3
4 /*
5 ID: yanglei4
6 LANG: JAVA
7 TASK:bigbrn
8 */
9 public class bigbrn {
10 public static int min(int a, int b) {
11 if (a < b) return a;
12 else return b;
13 }
14 public static int min3(int a, int b, int c) {
15 return min(a, min(b, c));
16 }
17 public static void main(String[] args) throws IOException {
18 BufferedReader f = new BufferedReader(new FileReader("bigbrn.in"));
19 PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("bigbrn.out")));
20 StringTokenizer st = new StringTokenizer(f.readLine());
21 int N = Integer.parseInt(st.nextToken());
22 int T = Integer.parseInt(st.nextToken());
23 int[][] map = new int[N][N];
24 for (int i = 0; i < T; i++) {
25 st = new StringTokenizer(f.readLine());
26 int x = Integer.parseInt(st.nextToken());
27 int y = Integer.parseInt(st.nextToken());
28 map[x - 1][y - 1] = -1;
29 }
30
31 for (int i = 0; i < N; i++) {
32 if (map[0][i]!= -1)
33 map[0][i] = 1;
34 if (map[i][0]!= -1)
35 map[i][0] = 1;
36 }
37
38
39 for (int i = 1; i < N; i++)
40 for (int j = 1; j < N; j++) {
41 if (map[i][j] != -1) {
42 int temp = min3(map[i - 1][j], map[i][j - 1], map[i - 1][j - 1]);
43 if (temp != -1) map[i][j] = temp + 1;
44 else map[i][j] = 1;
45 }
46 }
47
48 int max = 0;
49 for (int i = 0; i < N; i++)
50 for (int j = 0; j < N; j++)
51 if (map[i][j] != 0 && map[i][j] > max)
52 max = map[i][j];
53
54 out.println(max);
55 out.close();
56 System.exit(0);
57 }
58 }
59
應該算是一個比較基本的DP吧,狀態轉移方程也不難想,但是我最開始寫成了N^3的了
首先就是用Map[i][j]來表示以i,j為右下角的最大的square的大小
初始化就是第一行,第一列,如果不是#,那么肯定是1
然后對于i,j,我們需要觀察i - 1,j - 1,因為是square,所以只跟這個有關
如果在第i行,第j列上面,從當前位置開始,連續map[i-1][j-1]個位置,沒有#的話,那么map[i][j] = map[i-1][j-1]+1
我就是在判斷連續map[i-1][j-1]這個地方出了問題,我又加了一層循環,所以就變成了N^3的了,然后果然TLE了
這個地方完全沒必要用循環一個一個去判斷,因為其實你已經有結果了,這個結果就是map[i-1][j]和map[i][j-1]里面小的那個
map[i-1][j]肯定就是從當前位置開始,在第j列上,向上最多可以走多少步不碰到#
因為這時候實際上你已經確定了,#只有可能出現在第i行,第j列上,因為map[i-1][j-1]不是#就保證了這一點
于是,找到兩個方向上走的比較近的那個數,如果這個數是小于map[i-1][j-1]的,那么map[i][j]就等于這個數
否則,map[i][j] = map[i-1][j-1]+1
這個地方的重點就是,如果map[i-1][j-1]不是#,那么就保證了#只能在第i行,第j列上面。
只需要檢查這兩個就可以
然后我們就可以來看map[i-1][j],map[i][j-1],這兩個東西其實跟map[i-1][j-1]共享了上面的一塊。
如果在第i行,第j列上面出現了#,那么map[i-1][j],map[i][j-1]肯定比map[i-1][j-1]小
否則,我們的square最大也就只能是map[i-1][j-1]+1,因為map[i-1][j-1]已經是以i-1,j-1為右下角最大的square了
于是狀態轉移方程就是
map[i][j] = min (map[i-1][j],map[i][j-1],map[i-1][j-1]) + 1, map[i][j] != '#'