leetcode 903. DI序列的有效排列


題目描述:

我們給出 S,一個源於 {'D', 'I'} 的長度為 n 的字符串 。(這些字母代表 “減少” 和 “增加”。)
有效排列 是對整數 {0, 1, ..., n} 的一個排列 P[0], P[1], ..., P[n],使得對所有的 i:

如果 S[i] == 'D',那么 P[i] > P[i+1],以及;
如果 S[i] == 'I',那么 P[i] < P[i+1]。
有多少個有效排列?因為答案可能很大,所以請返回你的答案模 10^9 + 7.

 

示例:

輸入:"DID"
輸出:5
解釋:
(0, 1, 2, 3) 的五個有效排列是:
(1, 0, 3, 2)
(2, 0, 3, 1)
(2, 1, 3, 0)
(3, 0, 2, 1)
(3, 1, 2, 0)

 

提示:

  1. 1 <= S.length <= 200
  2. S 僅由集合 {'D', 'I'} 中的字符組成。

 

思路分析:

我們用 dp(i, j) 表示確定了排列中到 P[i] 為止的前 i + 1 個元素,並且 P[i] 和未選擇元素的相對大小為 j 的方案數(即未選擇的元素中,有 j 個元素比 P[i] 小)。在狀態轉移時,dp(i, j) 會從 dp(i - 1, k) 轉移而來,其中 k 代表了 P[i - 1] 的相對大小。如果 S[i - 1] 為 D,那么 k 不比 j 小;如果 S[i - 1] 為 I,那么 k 必須比 j 小。

 

代碼:

 1 class Solution {
 2 public:
 3     int mod = 1e9+7;
 4     int numPermsDISequence(string S) {
 5         int n = S.size();
 6         if(n==0)
 7             return 0;
 8         vector<vector<int>> dp(n+1, vector<int>(n+1, 0));
 9         for(int i=0; i<n+1; i++)
10             dp[0][i]=1;
11         for(int i=1; i<=n; i++)
12         {
13             for(int j=0; j<=i; j++)
14             {
15                 if(S[i-1]=='D')
16                 {
17                     for(int k=j; k<i; k++)
18                     {
19                         dp[i][j] += dp[i-1][k];
20                         dp[i][j] %= mod;
21                     }
22                 }
23                 else
24                 {
25                     for(int k=0; k<j; k++)
26                     {
27                         dp[i][j] += dp[i-1][k];
28                         dp[i][j] %= mod;
29                     }
30                 }
31             }
32         }
33         int ans = 0;
34         for(int i=0; i<=n; i++)
35         {
36             ans += dp[n][i];
37             ans %= mod;
38         }
39         return ans;
40     }
41 };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM