题目链接:
题目大意:
给一个只含‘I','D','?'三种字符的字符串,I表示当前数字大于前面的数字,D表示当前的数字小于前面一位的数字,?表示当前位既可以小于又可以大于。
问1~n的排列中有多少个满足该字符串。
解题思路:
计数dp.
dp[i][j]表示长度为i字符串,最后一个数为j时,能达到满足给定字符串的1~i+1的排列个数。
转移方程:
当S[i]='I'时,当前如果为j的话,前面的一位肯定要小于j,dp[i][j]+=Mi[j-1] ; //Mi[i]表示前面一位下标小于等于i dp[][1~i]的和
当S[i]='D'时,dp[i][j]+=(la-Mi[j-1]); //前一位要大于等于j
当S[i]='?'时,dp[i][j]+=la; //la表示前一位所有的状态总和.
注意递推的时候,前i位只和相对大小有关,与绝对大小无关,所以都用1~i表示,当增加一位时,就变成了1~i+1,如果当前为j,前面的小于j的状态不变,大于等于j的状态k所表示的值 现在表示k+1的值,这样就从1~i等价的转化成了1~i+1,这样考虑就不用考虑1~n的放法了,递推到n位时肯定都是1~n了。
代码:
#include #include #include #include #include #include #include #include