package class_2023_03_2_week; import java.util.Arrays; // 来自学员问题 // 给定N、M两个参数 // 一共有N个格子,每个格子可以涂上一种颜色,颜色在M种里选 // 当涂满N个格子,并且M种颜色都使用了,叫一种有效方法 // 求一共有多少种有效方法 // 1 <= N, M <= 5000 // 返回结果比较大,请把结果 % 1000000007 之后返回 public class Code03_FillCellsUseAllColorsWays { // 暴力方法 // 为了验证 public static int ways1(int n, int m) { return process(new int[n], new boolean[m + 1], 0, n, m); } public static int process(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 += process(path, set, i + 1, n, m); } return ans; } } // 正式方法 // 时间复杂度O(N*M) 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("n : " + n); System.out.println("m : " + m); System.out.println("ans1 : " + ans1); System.out.println("ans2 : " + ans2); break; } } } 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("性能测试结束"); } }