动态规划一般都是逆向递推,就是从结果来推理过程。这题是正向递推 ,从当前的数值推对后面结果的影响。
解题思路:
当前的概率是前面6个值承六分之一的和
正向递推:当前的值对后面的6个值都有影响,即相加。
1 2 3 4 5 6 7 8 9 10 11 12 13 func dicesProbability (n int ) []float64 { dp := []float64 {(1. )/(6. ),(1. )/(6. ),(1. )/(6. ),(1. )/(6. ),(1. )/(6. ),(1. )/(6. )} for i:=2 ;i<=n;i++{ tmp := make ([]float64 ,5 *i+1 ) for j:=0 ; j<len (dp); j++{ for k:=0 ; k<6 ;k++{ tmp[k+j] += dp[j]*(1. )/(6. ) } } dp = tmp } return dp }
复杂度分析:
时间复杂度$O(n^2)$
空间复杂度$O(n)$
每个数都必须乘2, 乘3, 乘5这样才能保证求出所有的丑数,而且还要保证丑数的顺序
设置3个索引a, b, c,分别记录前几个数已经被乘2, 乘3, 乘5了,比如a表示前(a-1)个数都已经乘过一次2了,下次应该乘2的是第a个数;b表示前(b-1)个数都已经乘过一次3了,下次应该乘3的是第b个数;c表示前(c-1)个数都已经乘过一次5了,下次应该乘5的是第c个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 func nthUglyNumber (n int ) int { dp := make ([]int ,n+1 ) dp[1 ]=1 a,b,c := 1 ,1 ,1 for i:=2 ; i <=n;i++{ n1,n2,n3 := dp[a]*2 ,dp[b]*3 ,dp[c]*5 dp[i] = min(n1,min(n2,n3)) if dp[i] == n1{a++} if dp[i] == n2{b++} if dp[i] == n3{c++} } return dp[n] } func min (a, b int ) int { if a < b { return a } return b }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 func longestCommonSubsequence (text1 string , text2 string ) int { m,n := len (text1),len (text2) dp := make ([][]int ,m+1 ) for i,_ := range dp{ dp[i] = make ([]int ,n+1 ) } for i:=1 ;i<=m;i++{ c1 := text1[i-1 ] for j:= 1 ;j<=n;j++{ c2 := text2[j-1 ] if c1 == c2{ dp[i][j] = dp[i-1 ][j-1 ] + 1 }else { dp[i][j] = max(dp[i-1 ][j],dp[i][j-1 ]) } } } return dp[m][n] } func max (a,b int ) int { if a < b{ return b }else { return a } }