Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8b35ff7

Browse files
Create Readme.md
1 parent 060b463 commit 8b35ff7

File tree

1 file changed

+20
-0
lines changed
  • Dynamic_Programming/3389.Minimum-Operations-to-Make-Character-Frequencies-Equal

1 file changed

+20
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
### 3389.Minimum-Operations-to-Make-Character-Frequencies-Equal
2+
3+
此题的突破口是对所有可能的频率进行尝试,暴力地从1枚举到max_freq(对应出现频次最多的字母),然后考察是否有一种方法能够将所有字符的频次都变换成target。
4+
5+
对于题目中的规则,我们最需要深刻体会的就是第三条。事实上,我们不会将某个字符连续变换两次。比如说,a->b->c,那这两次变换,还不如直接删除a,添加c来得直观。所以唯一使用规则三的情景就是:对于字母表相邻的两种字符x和y,如果x需要删除一些,y需要增加一些,那么我们不妨将部分的x转化为y,以节省操作。更具体的,如果x需要删除a个,y需要增加b个,普通的"删除+增加"的操作需要a+b次,但是如果将c=min(a,b)个x转化为y次,我们就额外节省了c次操作。
6+
7+
此题的复杂之处在于,即使我们确定了某个目标频次target,但规则同时也允许部分字符的频次变成零。对于这两个不同的"做法",需要考虑的策略其实也是不同的。因此我们对于a->z的的每个字符,都要考虑到它的两种"做法"。
8+
9+
假设我们考虑相邻的两个字符i-1和字符i。令`diff[i]=freq[i]-target`,正则表示相比于target多了,负表示相比于target还亏欠。定义dp[i][0]表示对字符i采取清零操作的总最小代价;dp[i][1]表示对字符i变换成target频次的总最小代价。
10+
11+
1. 如果对字符i采取清零,即dp[i][0],那么所需要的操作数必然是freq[i],与之前的状态无关。故`dp[i][0] = min(dp[i-1][0], dp[i-1][1]) + freq[i]`;
12+
13+
2. 如果对字符i变换成目标targt,那么我们分两种情况:
14+
* 不采用规则3,只靠增删,那么同理有`dp[i][1] = min(dp[i-1][0], dp[i-1][1]) + abs(diff[i])`
15+
* 采用规则3,同时前一个字符的操作是通过删减达到清零,这就意味着a=freq[i-1],b=abs(diff[i]),故c=min(a,b),且有`dp[i][1] = dp[i-1][0]+abs(diff[i])-c`
16+
* 采用规则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`
17+
18+
最终对于target而言,最优解就是遍历完26个字母后的`min(dp[25][0],dp[25][1])`
19+
20+
全局最取遍历所有target之后的最优解。

0 commit comments

Comments
(0)

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