modify code

master
algorithmzuo 2 years ago
parent 3b75509cf5
commit b13b1e0488

@ -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);
}
}
}
}

@ -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;
}
}
Loading…
Cancel
Save