二维动态规划(下)
| |
| int numDistinct(char *s, char *t) { |
| const int MOD = 1e9 + 7; |
| int lenS = strlen(s); |
| int lenT = strlen(t); |
| |
| |
| int dp[lenS + 1][lenT + 1]; |
| |
| for (int i = 0; i <= lenS; ++i) dp[i][0] = 1; |
| |
| for (int i = 1; i <= lenT; ++i) dp[0][i] = 0; |
| |
| for (int i = 1; i <= lenS; ++i) { |
| for (int j = 1; j <= lenT; ++j) { |
| |
| dp[i][j] = dp[i - 1][j]; |
| |
| if (s[i - 1] == t[j - 1]) |
| dp[i][j] = (dp[i][j] + dp[i - 1][j - 1]) % MOD; |
| } |
| } |
| return dp[lenS][lenT]; |
| } |
| |
| int numDistinct(char *s, char *t) { |
| const int MOD = 1e9 + 7; |
| int lenS = strlen(s); |
| int lenT = strlen(t); |
| |
| |
| int dp[lenT + 1]; |
| |
| |
| memset(dp, 0, sizeof(int) * (lenT + 1)); |
| dp[0] = 1; |
| |
| |
| for (int i = 1; i <= lenS; ++i) { |
| for (int j = lenT; j >= 1; j--) { |
| |
| |
| if (s[i - 1] == t[j - 1]) |
| dp[j] = (dp[j] + dp[j - 1]) % MOD; |
| } |
| } |
| return dp[lenT]; |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| |
| int editDistance(char *s1, char *s2, int a, int b, int c) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| |
| int dp[len1 + 1][len2 + 1]; |
| |
| dp[0][0] = 0; |
| |
| for (int i = 1; i <= len2; ++i) |
| dp[0][i] = i * a; |
| |
| for (int i = 1; i <= len1; ++i) |
| dp[i][0] = i * b; |
| |
| for (int i = 1; i <= len1; ++i) { |
| for (int j = 1; j <= len2; ++j) { |
| |
| |
| |
| |
| |
| |
| |
| |
| int p1 = 0x7fffffff; |
| if (s1[i - 1] == s2[j - 1]) |
| p1 = dp[i - 1][j - 1]; |
| int p2 = 0x7fffffff; |
| if (s1[i - 1] != s2[j - 1]) |
| p2 = dp[i - 1][j - 1] + c; |
| int p3 = dp[i][j - 1] + a; |
| int p4 = dp[i - 1][j] + b; |
| dp[i][j] = min(min(p1, p2), min(p3, p4)); |
| } |
| } |
| return dp[len1][len2]; |
| } |
| |
| int minDistance(char *word1, char *word2) { |
| return editDistance(word1, word2, 1, 1, 1); |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| |
| int editDistance(char *s1, char *s2, int a, int b, int c) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| |
| int dp[len1 + 1][len2 + 1]; |
| |
| dp[0][0] = 0; |
| |
| for (int i = 1; i <= len2; ++i) |
| dp[0][i] = i * a; |
| |
| for (int i = 1; i <= len1; ++i) |
| dp[i][0] = i * b; |
| |
| for (int i = 1; i <= len1; ++i) { |
| for (int j = 1; j <= len2; ++j) { |
| |
| if (s1[i - 1] == s2[j - 1]) { |
| |
| dp[i][j] = dp[i - 1][j - 1]; |
| } else { |
| |
| dp[i][j] = min(min(dp[i - 1][j - 1] + c, dp[i][j - 1] + a), dp[i - 1][j] + b); |
| } |
| } |
| } |
| return dp[len1][len2]; |
| } |
| |
| |
| int minDistance(char *word1, char *word2) { |
| return editDistance(word1, word2, 1, 1, 1); |
| } |
| int min(int a, int b) { |
| return a > b ? b : a; |
| } |
| |
| |
| int editDistance(char *s1, char *s2, int a, int b, int c) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| int dp[len2 + 1]; |
| |
| dp[0] = 0; |
| |
| for (int i = 1; i <= len2; ++i) |
| dp[i] = i * a; |
| |
| int leftUp; |
| int backup; |
| for (int i = 1; i <= len1; ++i) { |
| leftUp = (i - 1) * b; |
| |
| dp[0] = i * b; |
| for (int j = 1; j <= len2; ++j) { |
| backup = dp[j]; |
| |
| if (s1[i - 1] == s2[j - 1]) { |
| |
| dp[j] = leftUp; |
| } else { |
| |
| dp[j] = min(min(leftUp + c, dp[j - 1] + a), dp[j] + b); |
| } |
| leftUp = backup; |
| } |
| } |
| return dp[len2]; |
| } |
| |
| |
| int minDistance(char *word1, char *word2) { |
| return editDistance(word1, word2, 1, 1, 1); |
| } |
| bool isInterleave(char *s1, char *s2, char *s3) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| int len3 = strlen(s3); |
| if (len1 + len2 != len3) return false; |
| |
| |
| bool dp[len1 + 1][len2 + 1]; |
| for (int i = 0; i <= len1; ++i) |
| memset(dp[i], 0, sizeof(bool) * (len2 + 1)); |
| dp[0][0] = true; |
| |
| for (int j = 1; j <= len2; ++j) { |
| if (s2[j - 1] != s3[j - 1]) break; |
| dp[0][j] = true; |
| } |
| |
| for (int i = 1; i <= len1; ++i) { |
| if (s1[i - 1] != s3[i - 1]) break; |
| dp[i][0] = true; |
| } |
| |
| |
| for (int i = 1; i <= len1; ++i) { |
| for (int j = 1; j <= len2; ++j) { |
| |
| dp[i][j] = (s1[i - 1] == s3[i + j - 1] && dp[i - 1][j]) |
| || (s2[j - 1] == s3[i + j - 1] && dp[i][j - 1]); |
| } |
| } |
| return dp[len1][len2]; |
| } |
| |
| bool isInterleave(char *s1, char *s2, char *s3) { |
| int len1 = strlen(s1); |
| int len2 = strlen(s2); |
| int len3 = strlen(s3); |
| if (len1 + len2 != len3) return false; |
| |
| bool dp[len2 + 1]; |
| memset(dp, 0, sizeof(bool) * (len2 + 1)); |
| dp[0] = true; |
| |
| for (int j = 1; j <= len2; ++j) { |
| if (s2[j - 1] != s3[j - 1]) break; |
| dp[j] = true; |
| } |
| |
| |
| for (int i = 1; i <= len1; ++i) { |
| |
| dp[0] = s1[i - 1] == s3[i - 1] && dp[0]; |
| for (int j = 1; j <= len2; ++j) { |
| |
| dp[j] = (s1[i - 1] == s3[i + j - 1] && dp[j]) |
| || (s2[j - 1] == s3[i + j - 1] && dp[j - 1]); |
| } |
| } |
| return dp[len2]; |
| } |
有效涂色问题
| package class068; |
| |
| import java.util.Arrays; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public class Code04_FillCellsUseAllColorsWays { |
| |
| |
| |
| public static int ways1(int n, int m) { |
| return f(new int[n], new boolean[m + 1], 0, n, m); |
| } |
| |
| |
| |
| |
| |
| public static int f(int[] path, boolean[] set, int i, int n, int m) { |
| if (i == n) { |
| Arrays.fill(set, false); |
| int colors = 0; |
| for (int c : path) { |
| if (!set[c]) { |
| set[c] = true; |
| colors++; |
| } |
| } |
| return colors == m ? 1 : 0; |
| } else { |
| int ans = 0; |
| for (int j = 1; j <= m; j++) { |
| path[i] = j; |
| ans += f(path, set, i + 1, n, m); |
| } |
| return ans; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| public static int MAXN = 5001; |
| |
| public static int[][] dp = new int[MAXN][MAXN]; |
| |
| public static int mod = 1000000007; |
| |
| public static int ways2(int n, int m) { |
| |
| |
| |
| for (int i = 1; i <= n; i++) { |
| dp[i][1] = m; |
| } |
| for (int i = 2; i <= n; i++) { |
| for (int j = 2; j <= m; j++) { |
| dp[i][j] = (int) (((long) dp[i - 1][j] * j) % mod); |
| dp[i][j] = (int) ((((long) dp[i - 1][j - 1] * (m - j + 1)) + dp[i][j]) % mod); |
| } |
| } |
| return dp[n][m]; |
| } |
| |
| public static void main(String[] args) { |
| |
| |
| |
| int N = 9; |
| int M = 9; |
| System.out.println("功能测试开始"); |
| for (int n = 1; n <= N; n++) { |
| for (int m = 1; m <= M; m++) { |
| int ans1 = ways1(n, m); |
| int ans2 = ways2(n, m); |
| if (ans1 != ans2) { |
| System.out.println("出错了!"); |
| } |
| } |
| } |
| System.out.println("功能测试结束"); |
| |
| System.out.println("性能测试开始"); |
| int n = 5000; |
| int m = 4877; |
| System.out.println("n : " + n); |
| System.out.println("m : " + m); |
| long start = System.currentTimeMillis(); |
| int ans = ways2(n, m); |
| long end = System.currentTimeMillis(); |
| System.out.println("取余之后的结果 : " + ans); |
| System.out.println("运行时间 : " + (end - start) + " 毫秒"); |
| System.out.println("性能测试结束"); |
| } |
| } |
删除至少几个字符可以变成另一个字符串的子串
| package class068; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| |
| |
| |
| |
| public class Code05_MinimumDeleteBecomeSubstring { |
| |
| |
| |
| public static int minDelete1(String s1, String s2) { |
| List<String> list = new ArrayList<>(); |
| f(s1.toCharArray(), 0, "", list); |
| |
| |
| |
| |
| |
| list.sort((a, b) -> b.length() - a.length()); |
| for (String str : list) { |
| if (s2.indexOf(str) != -1) { |
| |
| return s1.length() - str.length(); |
| } |
| } |
| return s1.length(); |
| } |
| |
| |
| public static void f(char[] s1, int i, String path, List<String> list) { |
| if (i == s1.length) { |
| list.add(path); |
| } else { |
| f(s1, i + 1, path, list); |
| f(s1, i + 1, path + s1[i], list); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| public static int minDelete2(String str1, String str2) { |
| char[] s1 = str1.toCharArray(); |
| char[] s2 = str2.toCharArray(); |
| int n = s1.length; |
| int m = s2.length; |
| |
| |
| int[][] dp = new int[n + 1][m + 1]; |
| for (int i = 1; i <= n; i++) { |
| dp[i][0] = i; |
| for (int j = 1; j <= m; j++) { |
| if (s1[i - 1] == s2[j - 1]) { |
| dp[i][j] = dp[i - 1][j - 1]; |
| } else { |
| dp[i][j] = dp[i - 1][j] + 1; |
| } |
| } |
| } |
| int ans = Integer.MAX_VALUE; |
| for (int j = 0; j <= m; j++) { |
| ans = Math.min(ans, dp[n][j]); |
| } |
| return ans; |
| } |
| |
| |
| |
| public static String randomString(int n, int v) { |
| char[] ans = new char[n]; |
| for (int i = 0; i < n; i++) { |
| ans[i] = (char) ('a' + (int) (Math.random() * v)); |
| } |
| return String.valueOf(ans); |
| } |
| |
| |
| |
| public static void main(String[] args) { |
| |
| |
| |
| int n = 12; |
| int v = 3; |
| int testTime = 20000; |
| System.out.println("测试开始"); |
| for (int i = 0; i < testTime; i++) { |
| int len1 = (int) (Math.random() * n) + 1; |
| int len2 = (int) (Math.random() * n) + 1; |
| String s1 = randomString(len1, v); |
| String s2 = randomString(len2, v); |
| int ans1 = minDelete1(s1, s2); |
| int ans2 = minDelete2(s1, s2); |
| if (ans1 != ans2) { |
| System.out.println("出错了!"); |
| } |
| } |
| System.out.println("测试结束"); |
| } |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步