We are given S, a length n string of characters from the set {'D', 'I'}. (These letters stand for "decreasing" and "increasing".)

valid permutation is a permutation P[0], P[1], ..., P[n] of integers {0, 1, ..., n}, such that for all i:

  • If S[i] == 'D', then P[i] > P[i+1], and;
  • If S[i] == 'I', then P[i] < P[i+1].

How many valid permutations are there?  Since the answer may be large, return your answer modulo 10^9 + 7.

Example 1:

Input: "DID"
Output: 5
Explanation:
The 5 valid permutations of (0, 1, 2, 3) are:
(1, 0, 3, 2)
(2, 0, 3, 1)
(2, 1, 3, 0)
(3, 0, 2, 1)
(3, 1, 2, 0) 这道题目出自LeetCode,可以采用动态规划方法来解决 这篇博客主要是对LeetCode给出的第一种时间复杂度为O(n^3)的动态规划解法进行解释,题目的大意不再具体解释,有点英文基础的查查百度也能知道
这个题说的是个什么意思。由于采用的是动态规划解法,所以要找出状态和状态转移方程。LeetCode给的那个解法里面把状态dp[i][j]确定为以下的含义:
我们每次只注重最后一个数字在整个数组序列中 小->大 排列后的位置,如果给数组编号为i = 0、1、...、n,我们关注的焦点dp[i][j]可以解释为长度为i+1的数组中某个方案中
其最后一个数字即第i个数字在这i+1个数字中处于第j+1小位置的方案的数量,比如dp[0][0]的意义就是长度为长度为1的数组{0}按字符串S的要求下重新排列后的新数组其第0个数字在整个数组中排最小的方案数字,而且易知dp[0][0]=1。
而且dp[0]只用dp[0][0]这一个元素,其他的用不上,对于每个i = 0、1、...、n,我们只用dp[i][0..i]这些元素。
状态转移方程的解释更加复杂,如果S[i-1]=='D',递减,则p[i]<p[i-1],这个时候dp[i][j]是所有dp[i-1][j<=k<=i-1]的和,k之所以小于i是因为对于dp[i-1]来说它一共就i个成员,下标访问到i会越界,k大等于j的原因不好解释,
有一个替换的问题在里面,因为dp[i]比dp[i-1]多一个元素,它们所代表的数组也是前者比后者多一个,由于dp[i]所属的数组方案中按 小->大的数组和dp[i-1]的那个数组中第k(1<=k<=i)个数字是一样的,这里我不知道怎么叙述好,
反正就是dp[i]所代表的那个长的最后一位可以使用dp[i-1]所代表的那个短的最后一位,因为是递减,可以把dp[i]代表的数组中多出来的那一个最大的数组顶在倒数第二个位置上;如果S[i-1]=='T',由于dp[i]所属的数组方案中按 小->大
的数组和dp[i-1]的那个数组中第k(1<=k<=i)个数字是一样的,dp[i][j]是所有dp[i-1][0<=k<j]的和。这个题的思路上确实是比较复杂的,也不是很好叙述清楚它的思路。这个题最后一个注意点就是要求模,记住每次求模即可。 下面直接上代码:
 int numPermsDISequence(string S){
int MOD = ;
int n = S.length();
int**dp = new int*[n + ];
for (int i = ; i <= n; i++)
dp[i] = new int[n + ];
for (int i = ; i <= n;i++)
for (int j = ; j <= n; j++){
if (i == )dp[i][j] = ;
else dp[i][j] = ;
}
for (int i = ; i <= n; i++){
for (int j = ; j <= i; j++){
if (S[i - ] == 'D'){
for (int k = j; k < i; k++){
dp[i][j] += dp[i - ][k];
dp[i][j] %= MOD;
}
}
else{
for (int k = ; k < j; k++){
dp[i][j] += dp[i - ][k];
dp[i][j] %= MOD;
}
}
}
} for (int i = ; i <= n; i++){
for (int j = ; j <= n; j++)
cout << dp[i][j] << " ";
cout << endl;
} int ans = ;
for (int i = ; i <= n; i++){
ans += dp[n][i];
ans %= MOD;
}
for (int i = ; i <= n; i++)
delete[]dp[i];
delete[]dp;
return ans;
}

												

动态规划——Valid Permutations for DI Sequence的更多相关文章

  1. [LeetCode] 903. Valid Permutations for DI Sequence DI序列的有效排列

    We are given S, a length n string of characters from the set {'D', 'I'}. (These letters stand for &q ...

  2. [Swift]LeetCode903. DI 序列的有效排列 | Valid Permutations for DI Sequence

    We are given S, a length n string of characters from the set {'D', 'I'}. (These letters stand for &q ...

  3. 903. Valid Permutations for DI Sequence

    We are given S, a length n string of characters from the set {'D', 'I'}. (These letters stand for &q ...

  4. leetcode903 Valid Permutations for DI Sequence

    思路: dp[i][j]表示到第i + 1个位置为止,并且以剩下的所有数字中第j + 1小的数字为结尾所有的合法序列数. 实现: class Solution { public: int numPer ...

  5. [Algo] 66. All Valid Permutations Of Parentheses I

    Given N pairs of parentheses “()”, return a list with all the valid permutations. Assumptions N > ...

  6. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  7. All LeetCode Questions List 题目汇总

    All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...

  8. leetcode hard

    # Title Solution Acceptance Difficulty Frequency     4 Median of Two Sorted Arrays       27.2% Hard ...

  9. 【LeetCode】分治法 divide and conquer (共17题)

    链接:https://leetcode.com/tag/divide-and-conquer/ [4]Median of Two Sorted Arrays [23]Merge k Sorted Li ...

随机推荐

  1. Kafka遇到30042ms has passed since batch creation plus linger time at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.valueOrError(FutureRecordMetadata.java:94)

    问题描述: 运行生产者线程的时候显示如下错误信息: Expiring 1 record(s) for XXX-0: 30042 ms has passed since batch creation p ...

  2. 位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  3. 飞旋treap

    虽然叫做非旋treap但是飞旋treap很带感所以就用这个名字了(SB) 这个东西是真的好写...... 主要的两个函数只有两个,rotate和splay,split和merge. merge就是大家 ...

  4. 【SQL】INSERT INTO SELECT语句与SELECT INTO FROM语句

    INSERT INTO SELECT语句与SELECT INTO FROM语句,都是将一个结果集插入到一个表中: #INSERT INTO SELECT语句 1.语法形式: Insert into T ...

  5. Matlab怎么修改显示数值格式/精度/小数位数

    参考:https://jingyan.baidu.com/article/7f41ecec1ad029593c095c70.html

  6. HDU 1584(蜘蛛牌 DFS)

    题意是在蜘蛛纸牌的背景下求 10 个数的最小移动距离. 在数组中存储 10 个数字各自的位置,用深搜回溯的方法求解. 代码如下: #include <bits/stdc++.h> usin ...

  7. 盒子显隐,伪类边框,盒子阴影,2d平面形变

    -盒子显隐 显隐的盒子尽量不影响其他盒子的布局 display:none; 消失的时候不占位置,显示的时候占位 opacity:0-1; 盒子透明度 overflow: hidden; 超出部分隐藏 ...

  8. Geometric regularity criterion for NSE: the cross product of velocity and vorticity 4: $u\cdot \om$

    在 [Berselli, Luigi C.; Córdoba, Diego. On the regularity of the solutions to the 3D Navier-Stokes eq ...

  9. IP、端口及远程服务器

  10. (五)Java工程化--Jenkins

    Jenkins简介 Jenkins 是一种用Java语言实现的持续集成工具,Jenkins是一个平台, 在此基础上实现下面两个目的. CI 持续集成(Continous Integration) CD ...