题意
给你一个字符串s,s[i] = ‘D’表示排列中a[i] > a[i+1],s[i] = ‘I’表示排列中a[i] < a[i+1]。
比如排列 {3, 1, 2, 7, 4, 6, 5} 表示为字符串 DIIDID。
题解
很巧妙的DP做法,$dp[i][j]$表示前i个满足字符串条件的结尾为j的 i 的排列,注意是i的排列,前面并没有数大于i。那又是如何往下递推呢?
如果s[i - 1]是’ I ‘,那么$dp[i][j] = dp[i-1][j-1] + dp[i-1][j-2] + .. + dp[i-1][1]$
如果s[i - 1]是‘D’,那么$dp[i][j] = dp[i-1][j] + dp[i-1][j+1] + … + dp[i-1][i]$,因为要令当前位为j,如果前面出现过j,就令前面的所有大于等于j的数+1,就能构造出新的排列了。
比如{1, 3, 5, 2, 4},要在第六位插入3,令 >= 3的数都+1,于是就构造出新的 排列{1, 4, 6, 2, 5, 3}。然后代码的话处理出前缀和$sum[i][j]$,就不用$dp[i][j]$了。
代码
1 |
|