From ad51a828733ffb78fd96dac7d2183fc4f730b7d3 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2024年12月17日 00:18:30 -0800 Subject: [PATCH 1/3] Create 3389.Minimum-Operations-to-Make-Character-Frequencies-Equal.cpp --- ...ns-to-Make-Character-Frequencies-Equal.cpp | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal.cpp diff --git a/Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal.cpp b/Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal.cpp new file mode 100644 index 000000000..3d319cc0f --- /dev/null +++ b/Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal.cpp @@ -0,0 +1,48 @@ +class Solution { +public: + int makeStringGood(string s) + { + vectorfreq(26); + for (char c : s) { + freq[c-'a']++; + } + int max_freq = *max_element(freq.begin(), freq.end()); + + int ret = INT_MAX/2; + vectordiff(26); + + for (int target = 1; target <= max_freq; target++) + { + for (int i=0; i<26; i++) + diff[i] = freq[i] - target; + vector>dp(26, vector(2, INT_MAX/2)); + + int carry; + dp[0][0] = freq[0]; + dp[0][1] = abs(diff[0]); + + for (int i=1; i<26; i++) + { + dp[i][0] = min(dp[i-1][0], dp[i-1][1]) + freq[i]; + + dp[i][1] = min(dp[i-1][0], dp[i-1][1]) + abs(diff[i]); + + if (i>=1 && diff[i-1]>0 && diff[i]<0) + { + int common = min(abs(diff[i-1]), abs(diff[i])); + dp[i][1] = min(dp[i][1], dp[i-1][1] + abs(diff[i])-common); + } + + if (i>=1 && freq[i-1]>0 && diff[i]<0) + { + int common = min(abs(freq[i-1]), abs(diff[i])); + dp[i][1] = min(dp[i][1], dp[i-1][0] + abs(diff[i])-common); + } + } + + ret = min(ret, min(dp[25][0], dp[25][1])); + } + + return ret; + } +}; From 060b463d9cd19fe828fff723bd29e1d5eefe6c87 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2024年12月17日 00:19:04 -0800 Subject: [PATCH 2/3] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 6c9b50aa1..51776579d 100644 --- a/Readme.md +++ b/Readme.md @@ -764,6 +764,7 @@ [3041.Maximize-Consecutive-Elements-in-an-Array-After-Modification](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/3041.Maximize-Consecutive-Elements-in-an-Array-After-Modification) (H-) [3082.Find-the-Sum-of-the-Power-of-All-Subsequences](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/3082.Find-the-Sum-of-the-Power-of-All-Subsequences) (H-) [3098.Find-the-Sum-of-Subsequence-Powers](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/3098.Find-the-Sum-of-Subsequence-Powers) (H) +[3389.Minimum-Operations-to-Make-Character-Frequencies-Equal](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal) (H) * ``基本型 I`` [198.House-Robber](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/198.House-Robber) (E) [213.House-Robber-II](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/213.House-Robber-II) (M+) From 8b35ff7af805ea26bcee99005f46704292f38fce Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2024年12月17日 00:39:23 -0800 Subject: [PATCH 3/3] Create Readme.md --- .../Readme.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/Readme.md diff --git a/Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/Readme.md b/Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/Readme.md new file mode 100644 index 000000000..c645d91c0 --- /dev/null +++ b/Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal/Readme.md @@ -0,0 +1,20 @@ +### 3389.Minimum-Operations-to-Make-Character-Frequencies-Equal + +此题的突破口是对所有可能的频率进行尝试,暴力地从1枚举到max_freq(对应出现频次最多的字母),然后考察是否有一种方法能够将所有字符的频次都变换成target。 + +对于题目中的规则,我们最需要深刻体会的就是第三条。事实上,我们不会将某个字符连续变换两次。比如说,a->b->c,那这两次变换,还不如直接删除a,添加c来得直观。所以唯一使用规则三的情景就是:对于字母表相邻的两种字符x和y,如果x需要删除一些,y需要增加一些,那么我们不妨将部分的x转化为y,以节省操作。更具体的,如果x需要删除a个,y需要增加b个,普通的"删除+增加"的操作需要a+b次,但是如果将c=min(a,b)个x转化为y次,我们就额外节省了c次操作。 + +此题的复杂之处在于,即使我们确定了某个目标频次target,但规则同时也允许部分字符的频次变成零。对于这两个不同的"做法",需要考虑的策略其实也是不同的。因此我们对于a->z的的每个字符,都要考虑到它的两种"做法"。 + +假设我们考虑相邻的两个字符i-1和字符i。令`diff[i]=freq[i]-target`,正则表示相比于target多了,负表示相比于target还亏欠。定义dp[i][0]表示对字符i采取清零操作的总最小代价;dp[i][1]表示对字符i变换成target频次的总最小代价。 + +1. 如果对字符i采取清零,即dp[i][0],那么所需要的操作数必然是freq[i],与之前的状态无关。故`dp[i][0] = min(dp[i-1][0], dp[i-1][1]) + freq[i]`; + +2. 如果对字符i变换成目标targt,那么我们分两种情况: + * 不采用规则3,只靠增删,那么同理有`dp[i][1] = min(dp[i-1][0], dp[i-1][1]) + abs(diff[i])` + * 采用规则3,同时前一个字符的操作是通过删减达到清零,这就意味着a=freq[i-1],b=abs(diff[i]),故c=min(a,b),且有`dp[i][1] = dp[i-1][0]+abs(diff[i])-c` + * 采用规则3,同时前一个字符的操作是通过删减达到target,这就意味着a=diff[i-1],b=abs(diff[i]),故c=min(a,b),且有`dp[i][1] = dp[i-1][0]+abs(diff[i])-c` + +最终对于target而言,最优解就是遍历完26个字母后的`min(dp[25][0],dp[25][1])` + +全局最取遍历所有target之后的最优解。

AltStyle によって変換されたページ (->オリジナル) /