From b13b1e0488e8b519afb84485396708bc81ce0228 Mon Sep 17 00:00:00 2001 From: algorithmzuo Date: Wed, 28 Jun 2023 00:48:00 +0800 Subject: [PATCH] modify code --- .../class43/Code03_PavingTile1.java | 79 ++++++++++++++++++ .../class43/Code03_PavingTile2.java | 83 +++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 体系学习班/class43/Code03_PavingTile1.java create mode 100644 体系学习班/class43/Code03_PavingTile2.java diff --git a/体系学习班/class43/Code03_PavingTile1.java b/体系学习班/class43/Code03_PavingTile1.java new file mode 100644 index 0000000..230b5e5 --- /dev/null +++ b/体系学习班/class43/Code03_PavingTile1.java @@ -0,0 +1,79 @@ +package class43; + +// 找到了贴瓷砖问题在线测试 +// 测试链接 : http://poj.org/problem?id=2411 +// 注册一个北京大学评测平台的号提交以下 +// 请同学们务必参考如下代码中关于输入、输出的处理 +// 这是输入输出处理效率很高的写法 +// 提交以下的code,提交时请把类名改成"Main" +// 本文件是状态压缩的动态规划版本,也就是课上讲的版本 +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StreamTokenizer; + +public class Code03_PavingTile1 { + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StreamTokenizer in = new StreamTokenizer(br); + PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); + while (in.nextToken() != StreamTokenizer.TT_EOF) { + int n = (int) in.nval; + in.nextToken(); + int m = (int) in.nval; + if (n != 0 || m != 0) { + long ans = ways(n, m); + out.println(ans); + out.flush(); + } + } + } + + // 状态压缩动态规划,最后一个版本 + // 其实其他版本也能通过 + public static long ways(int N, int M) { + if (N < 1 || M < 1 || ((N * M) & 1) != 0) { + return 0; + } + if (N == 1 || M == 1) { + return 1; + } + int big = N > M ? N : M; + int small = big == N ? M : N; + int sn = 1 << small; + int limit = sn - 1; + long[] dp = new long[sn]; + dp[limit] = 1; + long[] cur = new long[sn]; + for (int level = 0; level < big; level++) { + for (int status = 0; status < sn; status++) { + if (dp[status] != 0) { + int op = (~status) & limit; + dfs(dp[status], op, 0, small - 1, cur); + } + } + for (int i = 0; i < sn; i++) { + dp[i] = 0; + } + long[] tmp = dp; + dp = cur; + cur = tmp; + } + return dp[limit]; + } + + public static void dfs(long way, int op, int index, int end, long[] cur) { + if (index == end) { + cur[op] += way; + } else { + dfs(way, op, index + 1, end, cur); + if (((3 << index) & op) == 0) { + dfs(way, op | (3 << index), index + 1, end, cur); + } + } + } + +} diff --git a/体系学习班/class43/Code03_PavingTile2.java b/体系学习班/class43/Code03_PavingTile2.java new file mode 100644 index 0000000..adc9bae --- /dev/null +++ b/体系学习班/class43/Code03_PavingTile2.java @@ -0,0 +1,83 @@ +package class43; + +// 找到了贴瓷砖问题在线测试 +// 测试链接 : http://poj.org/problem?id=2411 +// 注册一个北京大学评测平台的号提交以下 +// 请同学们务必参考如下代码中关于输入、输出的处理 +// 这是输入输出处理效率很高的写法 +// 提交以下的code,提交时请把类名改成"Main" +// 本文件是轮廓线dp的版本,轮廓线dp的讲解在每周直播课 : +// 2022年9月第4周的课,看了就能懂 +// 这是很难的一类题型,不做要求,大厂几乎不考 +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.StreamTokenizer; + +public class Code03_PavingTile2 { + + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StreamTokenizer in = new StreamTokenizer(br); + PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); + while (in.nextToken() != StreamTokenizer.TT_EOF) { + int n = (int) in.nval; + in.nextToken(); + int m = (int) in.nval; + if (n != 0 || m != 0) { + long ans = ways(n, m); + out.println(ans); + out.flush(); + } + } + } + + // 轮廓线dp的版本 + // 看课,上面说了看哪的 + public static int MAXN = 12; + + public static int MAXM = (1 << MAXN); + + public static long[][][] dp = new long[MAXN][MAXN][MAXM]; + + public static long ways(int n, int m) { + for (int i = 0; i <= n; i++) { + for (int j = 0; j <= m; j++) { + for (int k = 0; k <= (1 << m); k++) { + dp[i][j][k] = -1; + } + } + } + return process(0, 0, 0, n, m); + } + + public static long process(int r, int c, int s, int n, int m) { + if (r == n) { + return s == 0 ? 1 : 0; + } + if (c == m) { + return process(r + 1, 0, s, n, m); + } + if (dp[r][c][s] != -1) { + return dp[r][c][s]; + } + long ans; + int cur = (s & (1 << c)) == 0 ? 0 : 1; + if (cur == 1) { + ans = process(r, c + 1, s ^ (1 << c), n, m); + } else { + long p1 = process(r, c + 1, s | (1 << c), n, m); + long next = c + 1 < m && (s & (1 << (c + 1))) == 0 ? 0 : 1; + long p2 = 0; + if (next == 0) { + p2 = process(r, c + 2, s, n, m); + } + ans = p1 + p2; + } + dp[r][c][s] = ans; + return ans; + } + +}