//初始化s=0 for(int j=1;j<=plen;j++){ //当s为空时,a*b*c*可以匹配 //当判断到下标j-1是*,j- 即dp[0][j]对应的下标j-1位true if(j==1)dp[0][j]=false; if(p.charAt(j-1)=='*'&&dp[0][j- ][j-2]; } //如果p的*前边字符和s当前字符不相等或者p的字符不是‘.' //这里分开写是为了好理解 else if(p.charAt(j-2)! =s.charAt(i-1)&&p.charAt(j-2)!
'*'情况,p[j]以前的字符和s[i]以前的字符匹配条件是p[j]==s[i]&& p[j-1]和s[i-1]以前的字符都匹配 3,p[j]=='*'分3种情况 (1),p[j-1]匹配0次&&p[j- 2]和s[i]匹配 (2),p[j-1]匹配1次(p[j-1]==s[i])&&p[j-2]和s[i-1]匹配 (3),p[j-1]匹配多次,p[j-1]==s[i] A,p[j]和s[i-1]匹配 B ] = true a[1][1] = match(bs[0], bp[0]) for j := 2; j < len(p)+1; j = j + 2 { a[0][j] = a[0][j- 2] || (a[i-1][j-1] && match(bs[i-1], bp[j-2])) || (a[i][j-1] && match(bs[i-1], bp[j-2])) || (a[i-1][j ] && match(bs[i-1], bp[j-2])) } else { a[i][j] = a[i-1][j-1] && match(bs[i-1], bp[j-1])
res = false; break; } } ans[j- 2] = res; for(int i = 0; i < 3; i++) { // 左端点的列 j-2列 计数减去 flag [number[i][j-2]]--; } } return ans; } }; 603ms C++
我们看下图的初始情况,ab,a*c*ab,其中a*,将会变成一个空串,所以在dp[0][2] = 1 ,它是由dp[0][0]决定的,这是一个状态转移,即当p[j-1] == '*'时,dp[0][j]=dp[0][j- =p[j-2]&&p[j-2]!='.' ,也就是kac,kb*ac,说明此时b*应该是一个空串,当是空串的转移方程前面提到过,dp[i][j]=dp[i][j-2] ② s[i-1]==p[j-2]||p[j-2]=='.' ,此时的*可以匹配0个,一个,多个前面的元素 a.当*匹配前面0个元素,也就是空串喽~`dp[i][j]=dp[i][j-2]` b.当*匹配前面一个元素时,也就是a
else: result[i][j] = result[i][j-2] or (result[i-1][j] and (s[i-1] == p[j-2] or p [j-2] == '.'))
然后就是找出骑士可以走的8个方向,假设骑士当前位置在(i, j),那么下一跳可能的位置是[i-1, j-2], [i-2, j-1], [i+1, j-2], [i+2, j-1], [i-2, j+1 return 0 elif k == 0: return 1 res = 0 for x, y in [[i-1, j- 2], [i-2, j-1], [i+1, j-2], [i+2, j-1], [i-2, j+1], [i-1, j+2], [i+1, j+2], [i+2, j+1]]:
在这种情况下,我们将dp[i][j]设置为dp[i][j-2],表示模式p中的p[j-2]和p[j-1]被忽略。 *代表多个前面的字符。 我们需要检查字符串s的当前字符s[i-1]和模式p的前一个字符p[j-2]是否匹配。如果匹配,我们可以将dp[i][j]设置为dp[i-1][j],表示可以将当前字符*匹配到字符串s的前一个字符。 如果模式p的当前字符p[j-1]为*,我们需要进一步分情况讨论: *代表0个前面的字符:设置dp[i][j]为dp[i][j-2],表示模式p中的p[j-2]和p[j-1]被忽略。 *代表多个前面的字符:首先设置dp[i][j]为dp[i][j-2],然后判断字符串s的当前字符s[i-1]与模式p的前一个字符p[j-2]是否匹配。
对长度为i逆序对为j的排列,枚举发现排列的首元素a1的可能取值为1,2,3…i,分别会和排列的后续元素a2…ai生成0,1,2…i-1个逆序对,则后续子排列a2,a3…ai的逆序对数分别为j,j-1,j- 2…j-(i-1),对应的排列数量分别为re[i-1][j],re[i-1][j-1],re[i-1][j-2]…re[i-1][j-(i-1)]。 显然,re[i][j]是re[i-1][j],re[i-1][j-1],re[i-1][j-2]…re[i-1][j-(i-1)]之和。 思路三.优化DP 观察上述DP的转移方程: re[i][j-1] = re[i-1][j-1] + re[i-1][j-2] + …+re[i-1][j - i + 1] + re[i-1][j -1- i + 1] re[i][j] = re[i-1][j] + re[i-1][j-1] + re[i-1][j-2] + … +re[i-1][j - i + 1] 发现规律: re
== 0 { // p为空字符串的情况 dp[0][0] = true } else if p[j-1] == '*' { // 如果p[j-1]为*,则可以认为匹配p和p[0:j- 2]一样,类似于情况2 dp[0][j] = dp[0][j-2] } } // 填充整个dp数组,注意i和j在dp中不变,但对应到字符串s/p中都要-1 for i := 1; i = 0 && (s[i-1] == p[j-2] || p[j-2] == '.') { // 对应情况1,有星且第一个字符匹配 dp[i][j] = dp[i][j-2] || dp [i-1][j] } else { // 对应情况2,有星且不匹配 dp[i][j] = dp[i][j-2] } } else if i !
=p[j-1]&&p[j-1]=='*',此时p[j-1]中指向的是*,可以匹配零个或多个前面的元素,而是否能取多个或1个字符要看j-2的字符是否和i-1的字符相同。 因此首先要判断p[j-2]==s[i-1]3.1. p[j-2]==s[i-1],p的j-2字符与s的i-1字符相同,可以让*进行匹配,这里有三种情况,即*取0个字符,取1个字符和取多个字符3.2. p [j-2]=='.' ,p的j-2字符为万能字符,可以让*进行匹配3.3. p[j-2]! = p[j-2] && p[j-2] !
想要dp[j][i]为1,需要满足下面两个条件中的任意一个: 1、dp[j-2][i] = 1,此时'*'代表空串 2、dp[j][i-1] = 1 且 pattern字符串j-2位置的字符和目标字符串 i-1位置的字符相同(因为0位置表示了空串,所以数组中i位置代表的是字符串中的i-1位置)或者说pattern字符串j-2位置的字符为'.' 如果两个条件都不满足,则dp[j][i]为0 即: if(p.charAt(j-1)=='*') arr[j][i] = arr[j-2][i] || (p.charAt(j-2)==s.charAt (i-1) || p.charAt(j-2)=='.') && arr[j][i-1]; 那如果遇到的不是*时,问题就很简单了,要么pattern字符串j-1位置的字符为'.' arr[j][i] = arr[j-2][i] || (p.charAt(j-2)==s.charAt(i-1) || p.charAt(j-2)=='.') && arr[j][i-1];
dp[i][j]也肯定是0,这个情况不用管 情况2: pattern[j-1]==’‘,即前一个字符为’\‘,然后以下两种可能的情况,只要有一种成立即可 1:匹配0个字符:dp[i][j]=dp[i][j- // 重复 0 次 if (j >= 2) { dp[i][j] |= dp[i][j- // 这里要用 | 连接, 不然重复 0 次的会直接覆盖 if (i >= 1 && j>=2 && (s[i-1] == p[j- 2] || p[j-2] == '.')) { dp[i][j] |= dp[i-1][j]; }
状态转移方程如下: dp_{i,j}=\frac{i}{i+j}+\frac{j}{i+j}\times\frac{j-1}{i+j-1}\times\frac{i}{i+j-2}\times dp_{i-1,j- 2}+\frac{j}{i+j}\times\frac{j-1}{i+j-1}\times\frac{j-2}{i+j-2}\times dp_{i,j-3} class Solution: def if j >= 2: dp[i][j] += j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2)*dp[i-1][j- 2] if j >= 3: dp[i][j] += j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2)*dp[
.*" 可翻译成空、一个点、两个点、三个点…多种情况,那么dp[i][j]为: dp[i][j]=\begin{cases} dp[i][j-2] \\ dp[i-1][j-2] \\ dp[i-2 ][j-2] \\ dp[i-3][j-2] \\ ...... \end{cases} 然而只需要任意一个中情况为true即可,即 dp[i][j]=dp[i][j-2]||dp[i-1][j-2]||dp[i-2][j-2]||...... 又两种思路: 数学 对上式的 i 减 1 得 dp[i-1][j] 的表达式: dp[i-1][j]=dp[i-1][j-2]||dp[i-2][j-2]||dp[i-3][j-2]||...... ='*'\\ dp[i][j-2]||((p[j-1]=='.'
匹配空 dp[i][j-2] 匹配1个 dp[i-1][j-2]…… //所以dp[i][j]=dp[i][j-2]||dp[i-1][j-2]||dp[i-2][j-2]…… //数学推导 dp[i-1][j]=dp[i-1][j-2]||dp[i-2][j-2]…… //dp[i][j]=dp[i][j-2]||dp[i-1][j] //如果 填表 for(int i=1;i<=m;++i) for(int j=1;j<=n;++j) if(p[j]=='*') dp[i][j]=dp[i][j-
如果dp[i][j-2]==true那么dp[i][j]肯定为true,因为可以把它看成一个空串。 ? 在这里插入图片描述 如果dp[i][j-2]不为true也不要紧,如果匹配串和模式串前一个字符可以匹配并且dp[i-1][j]为true,那么也可以匹配(a*和a ) ? 综上分析得到dp方程为: if(模式串当前为*) dp[i][j]==dp[i][j-2]||(dp[i-1][j]&&两串当前字符可以匹配) else dp[i][j]=dp[i-1][j-1]&&两串当前字符可以匹配 +) { if(p.charAt(j-1)=='*')//该位置为* { dp[i][j]=dp[i][j- 2)||p.charAt(j-2)=='.')
if (map[i][j-2]==0) { map[i][j-2]=4; //人推箱子往前走一步,把空地ID修改为箱子ID() //下面是对箱子原地进行判断 if(map[i][j-1]==7) //如果箱子原地为目的地 elseif (map[i][j-2]==3) { count++; map[i][j-2]=7; //ID为(目的地ID()+箱子ID()=7),表示已经把箱子推入了目的地。 if(map[i][j-2]==0) { count--; map[i][j-2]=4; //把箱子重新推到空地上,ID=箱子ID+空地ID=4。 if(map[i][j-2]==3) { map[i][j-2]=7; //把箱子推入了另一目的地,自然,ID也应是。 map[i][j-1]=9; //人站在了目的地上。
3.初始化前面之后,后面的从索引1开始匹配: 1.pattern的第j个字符为“*”(即是 pattern[j-1]=='*') 1.1如果dp[i][j-2]==true,那么dp[i][j]=true (相当于str的前i和pattern的前j-2个字符匹配,此时的*前面的那个字符出现了0次)。 1.2如果dp[i-1][j]==true且str[i-1]==pattern[j-2],则dp[i][j] =true。 1个字符和pattern的前j个字符匹配,并且str的第i个字符和pattern的第j - 1个字符相等,相当于‘*’前面的字符出现了1次) 1.3如果dp[i-1][j]=true且pattern[j-
yold(j-2)+sig4*(5-3*kappa+(9*kappa-1)*sigma-6*kappa*sig2)*yold(j-1)... +sigma*0.5*(sigma-1)*yold(J-2); else % Extrapolation at outflow ynew(J) = yold(J) yold(J-2)+sig4*(5-3*kappa+(9*kappa-1)*sigma-6*kappa*sig2)*yold(J-1)...
dp[i+1][j-1]+=dp[i][j];//放在两边 dp[i+2][j]+=dp[i][j];//放在左边 dp[i][j-2]+=dp[i][j];//放在右边 并且要满足约束条件。 j+1,i,i+1)&&check(i,i+1)) dp[i+2][j]+=dp[i][j]; if(ch(i,j- 2,j-1,j)&&cc(i-1,j+1,j-1,j)&&check(j-1,j)) dp[i][j-2]+=dp[i][j];