中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

最近新聞大事件摘抄游戲優(yōu)化大師有用嗎

最近新聞大事件摘抄,游戲優(yōu)化大師有用嗎,想做代理商去哪找項(xiàng)目,西安網(wǎng)絡(luò)營銷公司排名文章目錄 競賽鏈接Q1:2848. 與車相交的點(diǎn)解法1——排序后枚舉解法2——差分?jǐn)?shù)組?差分?jǐn)?shù)組相關(guān)題目列表📕1094. 拼車1109. 航班預(yù)訂統(tǒng)計(jì)2381. 字母移位 II2406. 將區(qū)間分為最少組數(shù)解法1——排序貪心優(yōu)先隊(duì)列解法2——差分?jǐn)?shù)組 2772. 使數(shù)組中的所有元素…

文章目錄

  • 競賽鏈接
  • Q1:2848. 與車相交的點(diǎn)
    • 解法1——排序后枚舉
    • 解法2——差分?jǐn)?shù)組?
    • 差分?jǐn)?shù)組相關(guān)題目列表📕
      • 1094. 拼車
      • 1109. 航班預(yù)訂統(tǒng)計(jì)
      • 2381. 字母移位 II
      • 2406. 將區(qū)間分為最少組數(shù)
        • 解法1——排序貪心+優(yōu)先隊(duì)列
        • 解法2——差分?jǐn)?shù)組
      • 2772. 使數(shù)組中的所有元素都等于零
      • 2528. 最大化城市的最小供電站數(shù)目(?差分?jǐn)?shù)組 + 二分查找答案)
      • 最大化最小化相關(guān)題目列表📕
  • Q2:2849. 判斷能否在給定時間到達(dá)單元格(腦筋急轉(zhuǎn)彎、貪心)
  • Q3:2850. 將石頭分散到網(wǎng)格圖的最少移動次數(shù)???(全排列和狀態(tài)壓縮)
    • 解法1——枚舉全排列
    • 解法2——最小費(fèi)用最大流 (TODO)
    • 解法3——狀壓DP
    • 涉及到「匹配」的題目列表📕
      • 1947. 最大兼容性評分和
        • 解法1——枚舉全排列
        • 解法2——狀態(tài)壓縮DP
      • 1349. 參加考試的最大學(xué)生數(shù)🚹(狀態(tài)壓縮DP)
      • LCP 04. 覆蓋🚹(TODO 二分圖匹配 & 狀態(tài)壓縮DP)
        • 解法1——二分圖匹配
        • 解法2——狀態(tài)壓縮DP
      • 1879. 兩個數(shù)組最小的異或值之和(狀態(tài)壓縮DP)
      • 2172. 數(shù)組的最大與和(狀態(tài)壓縮DP)
  • Q4:2851. 字符串轉(zhuǎn)換?
    • 解法1——KMP + 矩陣快速冪優(yōu)化 DP 🐂
    • 解法2——找規(guī)律,無需矩陣快速冪(TODO)
    • [矩陣快速冪] 題目列表📕
  • 成績記錄

競賽鏈接

https://leetcode.cn/contest/weekly-contest-362/

Q1:2848. 與車相交的點(diǎn)

https://leetcode.cn/problems/points-that-intersect-with-cars/description/

在這里插入圖片描述

提示:
1 <= nums.length <= 100
nums[i].length == 2
1 <= starti <= endi <= 100

解法1——排序后枚舉

排序之后按順序枚舉,每次比較和上個區(qū)間結(jié)束位置之間的關(guān)系。

class Solution {public int numberOfPoints(List<List<Integer>> nums) {int ans = 0, last = -1;Collections.sort(nums, (x, y) -> x.get(0) - y.get(0));for (List<Integer> x: nums) {ans += Math.max(0, x.get(1) - Math.max(last + 1, x.get(0)) + 1);last = Math.max(last, x.get(1));}return ans;}
}

解法2——差分?jǐn)?shù)組?

https://leetcode.cn/problems/points-that-intersect-with-cars/solutions/2435384/chai-fen-shu-zu-xian-xing-zuo-fa-by-endl-3xpm/

關(guān)于差分可見:【算法基礎(chǔ)】1.5 前綴和與差分

class Solution {public int numberOfPoints(List<List<Integer>> nums) {int[] diff = new int[102];// 利用差分將區(qū)間內(nèi)所有位置 +1for (List<Integer> p: nums) {diff[p.get(0)]++;diff[p.get(1) + 1]--;}int ans = 0, s = 0;// 檢查各個位置  如果>0則ans++for (int d: diff) {s += d;if (s > 0) ans++;}return ans;}
}

差分?jǐn)?shù)組相關(guān)題目列表📕

題目列表來源:分享|【算法小課堂】差分?jǐn)?shù)組(Python/Java/C++/Go/JS)

1094. 拼車

https://leetcode.cn/problems/car-pooling/
在這里插入圖片描述
提示:

1 <= trips.length <= 1000
trips[i].length == 3
1 <= numPassengersi <= 100
0 <= fromi < toi <= 1000
1 <= capacity <= 10^5

用差分 表示 from 到 to 的范圍內(nèi)增加了多少人,然后再還原。

class Solution {public boolean carPooling(int[][] trips, int capacity) {int[] diff = new int[1002];// 構(gòu)造差分?jǐn)?shù)組for (int[] t: trips) {diff[t[1]] += t[0];diff[t[2]] -= t[0];}// 差分?jǐn)?shù)組的還原for (int i = 0; i <= 1000; ++i) {if (diff[i] > capacity) return false;diff[i + 1] += diff[i];}return true;}
}

1109. 航班預(yù)訂統(tǒng)計(jì)

https://leetcode.cn/problems/corporate-flight-bookings/

在這里插入圖片描述
提示
1 <= n <= 2 * 10^4
1 <= bookings.length <= 2 * 10^4
bookings[i].length == 3
1 <= firsti <= lasti <= n
1 <= seatsi <= 10^4

class Solution {public int[] corpFlightBookings(int[][] bookings, int n) {int[] ans = new int[n], diff = new int[n + 1];for (int[] booking: bookings) {diff[booking[0] - 1] += booking[2];diff[booking[1]] -= booking[2];}for (int i = 0; i < n; ++i) {ans[i] = diff[i];diff[i + 1] += diff[i];}return ans;}
}

2381. 字母移位 II

https://leetcode.cn/problems/shifting-letters-ii/

在這里插入圖片描述

提示
1 <= s.length, shifts.length <= 5 * 10^4
shifts[i].length == 3
0 <= starti <= endi < s.length
0 <= directioni <= 1
s 只包含小寫英文字母。

class Solution {public String shiftingLetters(String s, int[][] shifts) {int n = s.length();// 構(gòu)造差分?jǐn)?shù)組int[] diff = new int[n + 1];for (int[] shift: shifts) {int t = shift[2] == 1? 1: -1;diff[shift[0]] += t;diff[shift[1] + 1] -= t;}// 差分?jǐn)?shù)組和答案的還原char[] ans = new char[n];for (int i = 0; i < n; ++i) {ans[i] = op(s.charAt(i), diff[i]);diff[i + 1] += diff[i];}return String.valueOf(ans);}// 對字符 a 移動 xpublic char op(char a, int x) {return (char)(((a - 'a' + x % 26) + 26) % 26 + 'a');}
}

2406. 將區(qū)間分為最少組數(shù)

https://leetcode.cn/problems/divide-intervals-into-minimum-number-of-groups/
在這里插入圖片描述
提示:

1 <= intervals.length <= 1^05
intervals[i].length == 2
1 <= lefti <= righti <= 10^6

解法1——排序貪心+優(yōu)先隊(duì)列

按照區(qū)間的開始位置從小到大排序。
想象每個組合就是一個列表,我們使用有限隊(duì)列維護(hù)這些列表的末尾位置。
這樣每次枚舉到一個新的區(qū)間,檢查是否可以放入已有列表中,如果可以,就將一個已有列表的末尾位置換成當(dāng)前區(qū)間的結(jié)尾位置。

class Solution {public int minGroups(int[][] intervals) {Arrays.sort(intervals, (x, y) -> x[0] - y[0]);PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> x - y);for (int[] interval: intervals) {if (!pq.isEmpty() && pq.peek() < interval[0]) pq.poll();pq.offer(interval[1]);}return pq.size();}
}

解法2——差分?jǐn)?shù)組

差分還原中出現(xiàn)的最大值就是答案。

class Solution {public int minGroups(int[][] intervals) {TreeMap<Integer, Integer> diff = new TreeMap<>();int ans = 0, sum = 0;// 計(jì)算差分for (int[] interval: intervals) {diff.merge(interval[0], 1, Integer::sum);diff.merge(interval[1] + 1, -1, Integer::sum);}// 還原差分for (Map.Entry<Integer, Integer> entry: diff.entrySet()) {sum += entry.getValue();ans = Math.max(ans, sum);}return ans;}
}

2772. 使數(shù)組中的所有元素都等于零

https://leetcode.cn/problems/apply-operations-to-make-all-array-elements-equal-to-zero/

在這里插入圖片描述
提示:

1 <= k <= nums.length <= 10^5
0 <= nums[i] <= 10^6

有點(diǎn)差分的思想,又不太一樣。

貪心地從前往后枚舉每一個位置,只要 > 0 就減,< 0 就返回 false。

class Solution {public boolean checkArray(int[] nums, int k) {int n = nums.length, diff = 0, ans = 0;int[] x = new int[n];for (int i = 0; i < n; ++i) {if (i >= k) diff -= x[i - k];if (nums[i] > diff) {if (n - i < k) return false;ans += nums[i] - diff;      // 更新答案x[i] = nums[i] - diff;      // 記錄這個位置減去了多少diff = nums[i];             // 更新diff} else if (nums[i] < diff) return false;}return true;}
}

2528. 最大化城市的最小供電站數(shù)目(?差分?jǐn)?shù)組 + 二分查找答案)

https://leetcode.cn/problems/maximize-the-minimum-powered-city/
在這里插入圖片描述
提示:
n == stations.length
1 <= n <= 10^5
0 <= stations[i] <= 10^5
0 <= r <= n - 1
0 <= k <= 10^9

看到「最大化最小值」或者「最小化最大值」就要想到二分答案,這是一個固定的套路。

class Solution {public long maxPower(int[] stations, int r, int k) {int n = stations.length;long mn = Long.MAX_VALUE;// 計(jì)算差分?jǐn)?shù)組long[] cnt = new long[n + 1];for (int i = 0; i < n; ++i) {cnt[Math.max(0, i - r)] += stations[i];cnt[Math.min(n, i + r + 1)] -= stations[i];}// 差分?jǐn)?shù)組的還原for (int i = 0; i < n; ++i) {cnt[i + 1] += cnt[i];mn = Math.min(mn, cnt[i]);}// 二分查找答案long left = mn, right = mn + k;while (left < right) {long mid = left + right + 1 >> 1;if (!check(cnt, mid, r, k)) right = mid - 1;else left = mid;}return left;}// check過程類似 T2772. 使數(shù)組中的所有元素都等于零public boolean check(long[] cnt, long x, int r, int k) {long diff = 0;int n = cnt.length - 1;long[] d = new long[n];for (int i = 0; i < n; ++i) {if (i >= 2 * r + 1) diff -= d[i - 2 * r - 1];if (cnt[i] + diff < x) {d[i] = x - cnt[i] - diff;k -= d[i];diff = x - cnt[i];}}return k >= 0;}
}

最大化最小化相關(guān)題目列表📕

見:【算法】二分答案 對應(yīng)部分。

Q2:2849. 判斷能否在給定時間到達(dá)單元格(腦筋急轉(zhuǎn)彎、貪心)

https://leetcode.cn/problems/determine-if-a-cell-is-reachable-at-a-given-time/

在這里插入圖片描述

提示:
1 <= sx, sy, fx, fy <= 109
0 <= t <= 10^9

斜著走,一步頂兩步——相當(dāng)于可以同時橫著走和豎著走。 那么只要滿足垂直和水平方向中最長的那個距離就好了。

注意有個特例是:只走一步時,如果起點(diǎn)和終點(diǎn)相同就不可以了。

class Solution {public boolean isReachableAtTime(int sx, int sy, int fx, int fy, int t) {if (sx == fx && sy == fy && t == 1) return false;		// 特例return t >= Math.max(Math.abs(sx - fx), Math.abs(sy - fy));}
}

Q3:2850. 將石頭分散到網(wǎng)格圖的最少移動次數(shù)???(全排列和狀態(tài)壓縮)

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/
在這里插入圖片描述

提示:

grid.length == grid[i].length == 3
0 <= grid[i][j] <= 9
grid 中元素之和為 9

解法1——枚舉全排列

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435313/tong-yong-zuo-fa-zui-xiao-fei-yong-zui-d-iuw8/

將起始點(diǎn)和終點(diǎn)分別放入兩個列表,做全排列匹配。
枚舉所有全排列,比較各種情況下的移動次數(shù),得出最小移動次數(shù)。

class Solution {int ans = Integer.MAX_VALUE, sum = 0;boolean[] st = new boolean[9];public int minimumMoves(int[][] grid) {// 將起始點(diǎn)和終點(diǎn)放入列表List<int[]> src = new ArrayList<>(), dst = new ArrayList<>();for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {while (grid[i][j] > 1) {src.add(new int[]{i, j});grid[i][j]--;}if (grid[i][j] == 0) dst.add(new int[]{i, j});}}// dfs全排列dfs(0, src, dst);return ans;}public void dfs(int i, List<int[]> src, List<int[]> dst) {if (i == src.size()) {ans = Math.min(ans, sum);return;}for (int j = 0; j < dst.size(); ++j) {if (!st[j]) {int[] s = src.get(i), d = dst.get(j);sum += Math.abs(s[0] - d[0]) + Math.abs(s[1] - d[1]);st[j] = true;dfs(i + 1, src, dst);sum -= Math.abs(s[0] - d[0]) + Math.abs(s[1] - d[1]);st[j] = false;}}}
}

解法2——最小費(fèi)用最大流 (TODO)

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435313/tong-yong-zuo-fa-zui-xiao-fei-yong-zui-d-iuw8/

在這里插入代碼片

解法3——狀壓DP

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435319/zhuang-ya-dp-by-tsreaper-jiw0/

狀態(tài)壓縮DP相比全排列速度更快(48ms vs 3ms)

class Solution {public int minimumMoves(int[][] grid) {// 起始點(diǎn)和目的點(diǎn)放入兩個列表List<int[]> L = new ArrayList<>(), R = new ArrayList<>();for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (grid[i][j] == 0) R.add(new int[]{i, j});else {for (; grid[i][j] > 1; grid[i][j]--) {L.add(new int[]{i, j});}}}}// 狀態(tài)壓縮DPint n = L.size();int[] dp = new int[1 << n];Arrays.fill(dp, Integer.MAX_VALUE);dp[0] = 0;for (int i = 1; i < (1<<n); ++i) {// 計(jì)算 i 中有幾個二進(jìn)制等于 1——為了確定當(dāng)前目的點(diǎn)是哪個int cnt = 0;for (int j = 0; j < n; ++j) {cnt += i >> j & 1;}// 狀態(tài)轉(zhuǎn)移for (int j = 0; j < n; ++j) {   // 枚舉所有目標(biāo)點(diǎn)if ((i >> j & 1) == 1) {    // 檢查是否為1,即是否可以從前面轉(zhuǎn)移過來dp[i] = Math.min(dp[i], dp[i ^ (1 << j)] + cost(R.get(cnt - 1), L.get(j)));}}}return dp[(1<<n) - 1];}public int cost(int[] a, int[] b) {return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]);}
}

涉及到「匹配」的題目列表📕

題單來源:https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid/solutions/2435313/tong-yong-zuo-fa-zui-xiao-fei-yong-zui-d-iuw8/

1947. 最大兼容性評分和

https://leetcode.cn/problems/maximum-compatibility-score-sum/

在這里插入圖片描述
提示:
m == students.length == mentors.length
n == students[i].length == mentors[j].length
1 <= m, n <= 8
students[i][k] 為 0 或 1
mentors[j][k] 為 0 或 1

解法1——枚舉全排列

數(shù)據(jù)范圍很小,可以枚舉出所有學(xué)生和老師之間匹配的方案。

class Solution {int ans = 0;boolean[] st = new boolean[8];public int maxCompatibilitySum(int[][] students, int[][] mentors) {// 全排列dfs(students, mentors, 0, 0);return ans;}public void dfs(int[][] students, int[][] mentors, int i, int sum) {if (i == students.length) {ans = Math.max(ans, sum);return;}for (int j = 0; j < mentors.length; ++j) {if (st[j]) continue;st[j] = true;dfs(students, mentors, i + 1, sum + cp(students[i], mentors[j]));st[j] = false;}}// 計(jì)算某個學(xué)生和某個老師的兼容性評分public int cp(int[] s, int[] t) {int res = 0;for (int i = 0; i < s.length; ++i) {if (s[i] == t[i]) res++;}return res;}
}

解法2——狀態(tài)壓縮DP

class Solution {public int maxCompatibilitySum(int[][] students, int[][] mentors) {int n = students.length;int[][] dp = new int[n + 1][1<<n];  // dp[i][j]表示匹配完i個老師,和集合j的學(xué)生的最大匹配和// 枚舉每個狀態(tài)for (int i = 1; i < (1<<n); ++i) {int idx = Integer.bitCount(i);  // 計(jì)算該匹配哪個老師了// 枚舉每個學(xué)生for (int j = 0; j < n; ++j) {if ((i >> j & 1) == 1) {    // 如果可以轉(zhuǎn)移dp[idx][i] = Math.max(dp[idx][i], dp[idx - 1][i ^ (1<<j)] + cp(students[j], mentors[idx - 1]));}}}return dp[n][(1<<n) - 1];}// 計(jì)算某個學(xué)生和某個老師的兼容性評分public int cp(int[] s, int[] t) {int res = 0;for (int i = 0; i < s.length; ++i) {if (s[i] == t[i]) res++;}return res;}
}

1349. 參加考試的最大學(xué)生數(shù)🚹(狀態(tài)壓縮DP)

https://leetcode.cn/problems/maximum-students-taking-exam/
在這里插入圖片描述

提示:
seats 只包含字符 '.' 和'#'
m == seats.length
n == seats[i].length
1 <= m <= 8
1 <= n <= 8

將每一行選擇的位置用一個int變量表示。

枚舉每一行,再枚舉該行的狀態(tài),然后枚舉上一行的狀態(tài),檢測是否合理且可以轉(zhuǎn)移過來。
最后的答案就是最后一行各個狀態(tài)的最大值。


這里的合理包括:

  1. 該行本身要合理,—— 都要坐在正常的椅子上;同一行的兩個學(xué)生不能挨邊坐。
  2. 每一行和上一行之間不能有沖突——如果上一行的某一列已經(jīng)坐人了,那么該行該列的左右兩側(cè)就不能坐人了。
class Solution {public int maxStudents(char[][] seats) {int m = seats.length, n = seats[0].length;int[] states = new int[m];for (int i = 0; i < m; ++i) {states[i] = getMask(seats[i]);}// 一共m行,每行1<<n種狀態(tài)int[][] dp = new int[m + 1][1 << n];for (int i = 0; i < 1<<n; ++i) {// 判斷 i 是不是 states[0] 的子集 && 自己不沖突if (check(states[0], i) && op(i)) {dp[0][i] = Integer.bitCount(i);}}// 枚舉每一行for (int i = 1; i < m; ++i) {// 枚舉這一行的每個狀態(tài)for (int j = 0; j < 1<<n; ++j) {if (!check(states[i], j)) continue;     // 如果這個狀態(tài)不合理,就跳過// 枚舉上一行的每個狀態(tài)for (int k = 0; k < 1<<n; ++k) {if (!check(states[i - 1], k)) continue; // 如果這個狀態(tài)不合理,就跳過if (!confilt(k, j)) {               // 如果這個狀態(tài)和上一行不沖突dp[i][j] = Math.max(dp[i][j], dp[i - 1][k] + Integer.bitCount(j));}}}System.out.println();}return Arrays.stream(dp[m - 1]).max().getAsInt();}// 將一行的狀態(tài)用一個int表示public int getMask(char[] state) {int res = 0;for (int i = 0; i < state.length; ++i) {if (state[i] == '.') res |= 1 << i;}return res;}// 檢查狀態(tài)x是否是狀態(tài)state的子集,即是否可選 && 這個狀態(tài)x本身合法public boolean check(int state, int x) {if ((state | x) != state) return false;      // 需要x是state的子集return op(x);       }// 檢查x是否和y作為上一行沖突public boolean confilt(int x, int y) {for (int i = 0; i < 10; ++i) {if ((x >> i & 1) == 1) {    // 如果x這個位置有了// 那么y的相差一列的位置就不能有了if ((y >> i + 1 & 1) == 1 || (y >> i - 1 & 1) == 1) {return true;}}}return false;}// 檢查這一行的狀態(tài)本身是否合理,即檢查是否有兩個學(xué)生坐在挨邊的位置上public boolean op(int x) {for (int i = 0; i < 9; ++i) {if ((x >> i & 1) == 1 && (x >> i + 1 & 1) == 1) return false;}return true;}
}

LCP 04. 覆蓋🚹(TODO 二分圖匹配 & 狀態(tài)壓縮DP)

https://leetcode.cn/problems/broken-board-dominoes/

在這里插入圖片描述

限制:
1 <= n <= 8
1 <= m <= 8
0 <= b <= n * m

解法1——二分圖匹配

在這里插入代碼片

解法2——狀態(tài)壓縮DP

在這里插入代碼片

1879. 兩個數(shù)組最小的異或值之和(狀態(tài)壓縮DP)

https://leetcode.cn/problems/minimum-xor-sum-of-two-arrays/

在這里插入圖片描述
提示:
n == nums1.length
n == nums2.length
1 <= n <= 14
0 <= nums1[i], nums2[i] <= 10^7

class Solution {public int minimumXORSum(int[] nums1, int[] nums2) {int n = nums1.length;int[][] dp = new int[n + 1][1 << n];for (int i = 0; i <= n; ++i) Arrays.fill(dp[i], Integer.MAX_VALUE / 2);dp[0][0] = 0;// 枚舉nums1的每個狀態(tài)for (int i = 1; i < 1<<n; ++i) {int cnt = Integer.bitCount(i);// 枚舉每個位置for (int j = 0; j < n; ++j) {if ((i >> j & 1) == 1) {dp[cnt][i] = Math.min(dp[cnt][i], dp[cnt - 1][i ^ (1<<j)] + (nums1[j] ^ nums2[cnt - 1]));}}}return dp[n][(1<<n) - 1];}
}

2172. 數(shù)組的最大與和(狀態(tài)壓縮DP)

https://leetcode.cn/problems/maximum-and-sum-of-array/
在這里插入圖片描述

提示:
n == nums.length
1 <= numSlots <= 9
1 <= n <= 2 * numSlots
1 <= nums[i] <= 15

每個籃子可以放最多 2 個數(shù)字,那么可以分成有 2 組一模一樣的籃子處理。

注意——要將籃子的使用集合作為狀態(tài)。

class Solution {public int maximumANDSum(int[] nums, int numSlots) {int n = nums.length, m = 2 * numSlots, ans = 0;int[] dp = new int[1<<m];   // m個籃子的狀態(tài)// 枚舉每個籃子被選擇情況for (int i = 1; i < 1<<m; ++i) {// 計(jì)算該放入那個num了int cnt = Integer.bitCount(i);if (cnt > n) continue;// 枚舉每個被選擇的籃子for (int j = 0; j < m; ++j) {if ((i >> j & 1) == 1) {dp[i] = Math.max(dp[i], dp[i ^ (1<<j)] + (nums[cnt - 1] & (j % numSlots + 1)));}}ans = Math.max(ans, dp[i]);}return ans;}
}

Q4:2851. 字符串轉(zhuǎn)換?

https://leetcode.cn/problems/string-transformation/
在這里插入圖片描述

提示:
2 <= s.length <= 5 * 10^5
1 <= k <= 10^15
s.length == t.length
s 和 t 都只包含小寫英文字母。

解法1——KMP + 矩陣快速冪優(yōu)化 DP 🐂

https://leetcode.cn/problems/string-transformation/solutions/2435348/kmp-ju-zhen-kuai-su-mi-you-hua-dp-by-end-vypf/

計(jì)算有多少個 s 的循環(huán)同構(gòu)字符串等于 t,記作 c。這可以用 KMP 等字符串匹配算法解決,即尋找 t 在 s+s(去掉最后一個字符)中的出現(xiàn)次數(shù)。(用KMP計(jì)算出 s + s 中有幾個 t
關(guān)于 KMP 可見:我一定要 學(xué)會KMP字符串匹配

下面使用動態(tài)規(guī)劃來解決該問題——
定義 f[i][0] 表示 i 次操作后等于 t 的方案數(shù),f[i][1] 表示 i 次操作后不等于 t 的方案數(shù)。
在這里插入圖片描述
發(fā)現(xiàn) DP 遞推式可以寫成矩陣乘法形式,因此可以使用矩陣快速冪來優(yōu)化。(所謂矩陣快速冪,和普通快速冪的思想是一樣的。)
在這里插入圖片描述
快速冪可以完成從 O ( n ) O(n) O(n) O ( log ? n ) O(\log{n}) O(logn) 的優(yōu)化。

Q:為什么必須要使用矩陣快速冪?
A:因?yàn)?k 的數(shù)據(jù)范圍很大。( log ? n \log{n} logn 對應(yīng)的數(shù)據(jù)范圍是 1 0 18 10^{18} 1018

class Solution {final long MOD = (long)1e9 + 7;public int numberOfWays(String s, String t, long k) {int n = s.length();// kmp 求出 s+s(去掉最后一個字符) 中有幾個 tint c = kmpSearch(s + s.substring(0, n - 1), t);// 遞推矩陣long[][] m = {{c - 1, c},{n - c, n - 1 - c},};m = pow(m, k);      // 矩陣快速冪求結(jié)果// 根據(jù) s==t? 判斷初始狀態(tài) 對應(yīng)的答案return s.equals(t)? (int) m[0][0]: (int) m[0][1];}// kmp 返回 s 中有多少個 tpublic int kmpSearch(String s, String t) {int[] next = getNext(s.toCharArray());int c = 0;for (int i = 0, j = -1; i < s.length(); ++i) {while (j != -1 && s.charAt(i) != t.charAt(j + 1)) j = next[j];if (s.charAt(i) == t.charAt(j + 1)) j++;if (j == t.length() - 1) {c++;j = next[j];    // 匹配成功之后,記得要更新 j = next[j]}}return c;}// 求 next 數(shù)組public int[] getNext(char[] s) {int n = s.length;int[] next = new int[n];next[0] = -1;for (int i = 1, j = -1; i < n; ++i) {while (j != -1 && s[i] != s[j + 1]) j = next[j];if (s[i] == s[j + 1]) j++;next[i] = j;}return next;}// 矩陣快速冪public long[][] pow(long[][] a, long n) {long[][] res = {{1, 0}, {0, 1}};for (; n > 0; n /= 2) {if (n % 2 == 1) {res = multiply(res, a);}a = multiply(a, a);}return res;}// 矩陣乘法public long[][] multiply(long[][] a, long[][] b) {long[][] c = new long[2][2];for (int i = 0; i < 2; ++i) {for (int j = 0; j < 2; ++j) {c[i][j] = (a[i][0] * b[0][j] + a[i][1] * b[1][j]) % MOD;}}return c;}
}

解法2——找規(guī)律,無需矩陣快速冪(TODO)

https://leetcode.cn/problems/string-transformation/solutions/2435714/cjavapython-bu-xu-yao-ju-zhen-kuai-su-mi-cukc/

在這里插入代碼片

[矩陣快速冪] 題目列表📕

見:【算法】矩陣快速冪優(yōu)化動態(tài)規(guī)劃

成績記錄

本次沒有參加競賽。

http://www.risenshineclean.com/news/27197.html

相關(guān)文章:

  • 網(wǎng)站如何添加白名單百度關(guān)鍵詞收錄排名
  • 求職網(wǎng)站開發(fā)我想注冊一個網(wǎng)站怎么注冊
  • 高郵市建設(shè)網(wǎng)站龍崗seo網(wǎng)絡(luò)推廣
  • aso.net 網(wǎng)站開發(fā)營銷策略
  • 做app還是網(wǎng)站太原百度seo排名軟件
  • phpwind怎么做網(wǎng)站整站優(yōu)化工具
  • 怎樣做百度推廣網(wǎng)站天津谷歌優(yōu)化
  • 昆明學(xué)校網(wǎng)站建設(shè)長沙網(wǎng)站優(yōu)化體驗(yàn)
  • 網(wǎng)站做cdn需要注意什么意思百家號排名
  • 如何做網(wǎng)站靜態(tài)頁面?zhèn)€人推廣網(wǎng)站
  • 網(wǎng)站怎么做聯(lián)系我們頁面營銷技巧培訓(xùn)ppt
  • 請收網(wǎng)址999938關(guān)鍵詞優(yōu)化公司哪家效果好
  • 專業(yè)建網(wǎng)站平臺網(wǎng)絡(luò)營銷是做什么的工作
  • 中山網(wǎng)站建設(shè)哪家好seo是什么服務(wù)
  • 網(wǎng)站的排版網(wǎng)絡(luò)營銷成功的案例分析
  • 連云港專業(yè)網(wǎng)站制作公司seo快排軟件
  • 惠州seo推廣公司南寧seo平臺標(biāo)準(zhǔn)
  • 網(wǎng)站域名地址查詢網(wǎng)站創(chuàng)建
  • 如何進(jìn)行優(yōu)化短視頻關(guān)鍵詞優(yōu)化
  • 網(wǎng)站模板如何編輯軟件代引流推廣公司
  • 建設(shè)網(wǎng)站一般要多錢sem工作內(nèi)容
  • 南通網(wǎng)站建設(shè)規(guī)劃成都網(wǎng)絡(luò)營銷公司哪家好
  • 網(wǎng)站優(yōu)化要怎么做seo做什么網(wǎng)站賺錢
  • 網(wǎng)站不足之處人民網(wǎng)疫情最新消息
  • 麻城做網(wǎng)站做一個網(wǎng)站需要什么
  • 知名的電子商務(wù)網(wǎng)站紹興seo公司
  • 斗破蒼穹制作公司seo關(guān)鍵詞排名優(yōu)化官網(wǎng)
  • b2b網(wǎng)站建設(shè)怎么做大學(xué)生網(wǎng)絡(luò)營銷策劃方案書
  • 建設(shè)銀行網(wǎng)站網(wǎng)頁丟失口碑營銷的優(yōu)勢有哪些
  • 畢業(yè)設(shè)計(jì)做企業(yè)門戶網(wǎng)站今日新聞頭條大事