diff --git a/src/class47/Code01_StrangePrinter.java b/src/class47/Code01_StrangePrinter.java index f4fddc4..b7172db 100644 --- a/src/class47/Code01_StrangePrinter.java +++ b/src/class47/Code01_StrangePrinter.java @@ -11,12 +11,16 @@ public class Code01_StrangePrinter { return process1(str, 0, str.length - 1); } + // 要想刷出str[L...R]的样子! + // 返回最少的转数 public static int process1(char[] str, int L, int R) { if (L == R) { return 1; } + // L...R int ans = R - L + 1; for (int k = L + 1; k <= R; k++) { + // L...k-1 k....R ans = Math.min(ans, process1(str, L, k - 1) + process1(str, k, R) - (str[L] == str[k] ? 1 : 0)); } return ans; diff --git a/src/class47/Code02_RestoreWays.java b/src/class47/Code02_RestoreWays.java index 6069378..c9c583a 100644 --- a/src/class47/Code02_RestoreWays.java +++ b/src/class47/Code02_RestoreWays.java @@ -62,24 +62,24 @@ public class Code02_RestoreWays { // 如果i位置的数字变成了v, // 并且arr[i]和arr[i+1]的关系为s, // s==0,代表arr[i] < arr[i+1] 右大 - // s==1,代表arr[i] == arr[i+1] + // s==1,代表arr[i] == arr[i+1] 右=当前 // s==2,代表arr[i] > arr[i+1] 右小 // 返回0...i范围上有多少种有效的转化方式? public static int process1(int[] arr, int i, int v, int s) { if (i == 0) { // 0...i 只剩一个数了,0...0 - return ((s == 0 || s == 1) && (arr[i] == 0 || v == arr[i])) ? 1 : 0; + return ((s == 0 || s == 1) && (arr[0] == 0 || v == arr[0])) ? 1 : 0; } // i > 0 if (arr[i] != 0 && v != arr[i]) { return 0; } - // i>0 并且 i位置的数真的可以变成V, + // i>0 ,并且, i位置的数真的可以变成V, int ways = 0; - if (s == 0 || s == 1) { // [i - 1] [i] <= 右 + if (s == 0 || s == 1) { // [i] -> V <= [i+1] for (int pre = 1; pre < 201; pre++) { ways += process1(arr, i - 1, pre, pre < v ? 0 : (pre == v ? 1 : 2)); } - } else { // s == 2 i > 右 i-1 >= i > 右 + } else { // ? 当前 > 右 当前 <= max{左,右} for (int pre = v; pre < 201; pre++) { ways += process1(arr, i - 1, pre, pre == v ? 1 : 2); } @@ -87,6 +87,28 @@ public class Code02_RestoreWays { return ways; } + public static int zuo(int[] arr, int i, int v, int s) { + if (i == 0) { // 0...i 只剩一个数了,0...0 + return ((s == 0 || s == 1) && (arr[0] == 0 || v == arr[0])) ? 1 : 0; + } + // i > 0 + if (arr[i] != 0 && v != arr[i]) { + return 0; + } + // i>0 ,并且, i位置的数真的可以变成V, + int ways = 0; + if (s == 0 || s == 1) { // [i] -> V <= [i+1] + for (int pre = 1; pre < v; pre++) { + ways += zuo(arr, i - 1, pre, 0); + } + } + ways += zuo(arr, i - 1, v, 1); + for (int pre = v + 1; pre < 201; pre++) { + ways += zuo(arr, i - 1, pre, 2); + } + return ways; + } + public static int ways2(int[] arr) { int N = arr.length; int[][][] dp = new int[N][201][3]; diff --git a/src/class47/Code03_DinicAlgorithm.java b/src/class47/Code03_DinicAlgorithm.java index 3fcbe86..b04de12 100644 --- a/src/class47/Code03_DinicAlgorithm.java +++ b/src/class47/Code03_DinicAlgorithm.java @@ -67,6 +67,7 @@ public class Code03_DinicAlgorithm { boolean[] visited = new boolean[N]; visited[s] = true; while (!queue.isEmpty()) { + // u是当前节点 int u = queue.pollLast(); for (int i = 0; i < nexts.get(u).size(); i++) { Edge e = edges.get(nexts.get(u).get(i)); @@ -81,12 +82,17 @@ public class Code03_DinicAlgorithm { return visited[t]; } + // 当前来到了s点,s可变 + // 最终目标是t,t固定参数 + // r,收到的任务 + // 收集到的流,作为结果返回,ans <= r private int dfs(int s, int t, int r) { if (s == t || r == 0) { return r; } int f = 0; int flow = 0; + // s点从哪条边开始试 -> cur[s] for (; cur[s] < nexts.get(s).size(); cur[s]++) { int ei = nexts.get(s).get(cur[s]); Edge e = edges.get(ei);