动态规划——Valid Permutations for DI Sequence
We are given S, a length n string of characters from the set {'D', 'I'}. (These letters stand for "decreasing" and "increasing".)
A 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', thenP[i] > P[i+1], and; - If
S[i] == 'I', thenP[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的更多相关文章
- [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 ...
- [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 ...
- 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 ...
- leetcode903 Valid Permutations for DI Sequence
思路: dp[i][j]表示到第i + 1个位置为止,并且以剩下的所有数字中第j + 1小的数字为结尾所有的合法序列数. 实现: class Solution { public: int numPer ...
- [Algo] 66. All Valid Permutations Of Parentheses I
Given N pairs of parentheses “()”, return a list with all the valid permutations. Assumptions N > ...
- Swift LeetCode 目录 | Catalog
请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift 说明:题目中含有$符号则为付费题目. 如 ...
- All LeetCode Questions List 题目汇总
All LeetCode Questions List(Part of Answers, still updating) 题目汇总及部分答案(持续更新中) Leetcode problems clas ...
- leetcode hard
# Title Solution Acceptance Difficulty Frequency 4 Median of Two Sorted Arrays 27.2% Hard ...
- 【LeetCode】分治法 divide and conquer (共17题)
链接:https://leetcode.com/tag/divide-and-conquer/ [4]Median of Two Sorted Arrays [23]Merge k Sorted Li ...
随机推荐
- 深入理解JVM(2)——运行时数据区
1.运行时数据区 1.1.程序计数器 记录当前线程正在执行的字节码指令的地址,如果正在执行的是 Native 方法,这个计数器值则为空. 1.2.虚拟机栈 每个 Java 方法在执行的同时会创建一个栈 ...
- 去掉 Chrome(V66) 新标签页的8个缩略图
1.Chrome程序资源文件路径: C:\Program Files (x86)\Google\Chrome\Application\66.0.3359.181\resources.pak 2.下载C ...
- MQ服务器奔溃解决过程
1.MQ服务器崩溃调节: 今天具安卓前端反应, 从昨天下午开始线上服务器使用 电话号码登陆和 使用电话号码注册功能不能使用, 经过前端仔细排查怀疑是后端问题,之后经过与ios前端 确认, 定位为后端服 ...
- sea.js简单使用教程
sea.js简单使用教程 下载sea.js, 并引入 官网: http://seajs.org/ github : https://github.com/seajs/seajs 将sea.js导入项目 ...
- MAC OS进阶必看——这10个技巧让你秒变MAC达人
文章内容及图片来源于:什么值得买,如果涉及版权问题,请联系作者删除 文章收录于:风云社区(提供上千款各类mac软件的下载) 使用mac系统也有好几个年头,出色的办公效率以及越来越广的兼容性让mac成为 ...
- 应用调试(二)GDB
title: 应用调试(二)GDBdate: 2019/1/17 21:00:10 toc: true 应用调试(二)GDB gdb下载工具安装交叉工具链设置GDB介绍编译GDBtarget/host ...
- 第六节:框架搭建之EF的Fluent Api模式的使用流程
一. 前言 沉寂了约一个月的时间,今天用一篇简单的文章重新回归博客,主要来探讨一下Fluent Api模式在实际项目中的使用流程. 1. Fluent API属于EF CodeFirst模式的一种,E ...
- [再寄小读者之数学篇](2014-06-22 不等式 [中国科学技术大学2011年高等数学B考研试题])
证明不等式: $$\bex 1+x\ln\sex{x+\sqrt{1+x^2}}>\sqrt{1+x^2},\quad x>0. \eex$$ 证明: 令 $x=\tan t,\ 0< ...
- java中<T> T和T的区别
如果希望 getMax 方法的返回值类型为 T,就要这样去定义getMax方法: public T getMax() 如果希望 getMax 方法返回值的类型由调用者决定,那么就这么去定义 getMa ...
- UE导航系统详
配置 Navigation Crowd Manager Class 代理人管理类 可以自定义个 Navigation System Auto Create Navigation Data 导航数据在没 ...