【leetcode】LCP 19. 秋葉收藏集(UlBDOe)(DP)[中等]

Krone_發表於2020-10-03

連結

https://leetcode-cn.com/problems/UlBDOe/

耗時

解題:3 h 15 min
題解:58 min

題意

小扣出去秋遊,途中收集了一些紅葉和黃葉,他利用這些葉子初步整理了一份秋葉收藏集 leaves, 字串 leaves 僅包含小寫字元 r 和 y, 其中字元 r 表示一片紅葉,字元 y 表示一片黃葉。
出於美觀整齊的考慮,小扣想要將收藏集中樹葉的排列調整成「紅、黃、紅」三部分。每部分樹葉數量可以不相等,但均需大於等於 1。每次調整操作,小扣可以將一片紅葉替換成黃葉或者將一片黃葉替換成紅葉。請問小扣最少需要多少次調整操作才能將秋葉收藏集調整完畢。

思路

這是之前 leetcode 一個 CUP 的題,比賽時沒做出來,當時想用貪心,後來看答案才想 DP。由於之前看過答案,自己也沒有思路,所以這是照答案的思路寫的。

三個一維 dp,
dp[0][:] 是字串的字元的排列調整成「紅」一部分,即都換成 r 需要調整多少次;
dp[1][:] 是字串的字元的排列調整成「紅、黃」二部分,即換成 rrrr…yyy 最少需要調整多少次;
dp[2][:] 是字串的字元的排列調整成「紅、黃、紅」三部分,即換成 rrrrr…yyy…rrrr 最少需要調整多少次;

dp[0][i] 非常簡單,直接看 leaves[i] 是不是 r 就行了;
dp[1][i] 就有兩種情況了,…,兩種情況取最小

1. 從 dp[0][i-1] 全是 r 的轉移過來,變成 rrrr...rrrry
2. 從 上一個狀態 dp[1][i-1] 轉移過來,變成 rrrr...rrrry..y

dp[2][i] 和 dp[1][i] 差不多,

1. 從 dp[1][i-1] 轉移過來,變成 rrrr...rrrry..yr
2. 從 上一個狀態 dp[2][i-1] 轉移過來,變成 rrrr...rrrryyyy...yyyyr..r

狀態轉移方程:
{ d p [ 0 ] [ i ] = d p [ 0 ] [ i − 1 ] + 1 l e a v e s [ i ] = = ′ r ′ d p [ 1 ] [ i ] = m i n ( d p [ 0 ] [ i − 1 ] , d p [ 1 ] [ i − 1 ] ) + 1 l e a v e s [ i ] = = ′ y ′ d p [ 2 ] [ i ] = m i n ( d p [ 1 ] [ i − 1 ] , d p [ 2 ] [ i − 1 ] ) + 1 l e a v e s [ i ] = = ′ r ′ \begin{cases} dp[0][i] = dp[0][i-1] + 1^{leaves[i]=='r'} \\ dp[1][i] = min(dp[0][i-1], dp[1][i-1]) + 1^{leaves[i]=='y'} \\ dp[2][i] = min(dp[1][i-1], dp[2][i-1]) + 1^{leaves[i]=='r'} \end{cases} dp[0][i]=dp[0][i1]+1leaves[i]==rdp[1][i]=min(dp[0][i1],dp[1][i1])+1leaves[i]==ydp[2][i]=min(dp[1][i1],dp[2][i1])+1leaves[i]==r

時間複雜度: O ( n ) O(n) O(n)

AC程式碼

class Solution {
public:
    int minimumOperations(string leaves) {
        int n = leaves.size();
        vector<vector<int>> dp(3, vector<int>(n+1, 0));
        
        dp[0][1] = dp[2][1] = dp[1][1] = (leaves[0]=='r'?0:1);
        dp[2][2] = dp[1][2] = dp[1][1] + (leaves[1]=='y'?0:1);
        dp[0][2] = dp[0][1] + (leaves[1]=='r'?0:1);
        
        for(int i = 3; i <= n; ++i) {
            dp[0][i] = dp[0][i-1] + (leaves[i-1]=='r'?0:1);
            dp[1][i] = min(dp[0][i-1], dp[1][i-1]) + (leaves[i-1]=='y'?0:1);
            dp[2][i] = min(dp[1][i-1], dp[2][i-1]) + (leaves[i-1]=='r'?0:1);
        }
        
        return dp[2][n];
    }
};

相關文章