編程筆試題※python實現※動態規劃類

1.最長公共子序列長度
對於兩個字符串,請設計一個高效算法,求他們的最長公共子序列的長度。
思路:用兩個指針i和j從後往前遍歷s1和s2,如果s1[i]==s2[j],那麼這個字符一定在lcs中;否則的話,s1[i]和s2[j]這兩個字符至少有一個不在lcs中,需要丟棄一個。
步驟:1.明確dp數組含義 dp[i][j]的含義是:對於s1[1…i]和s2[1…j],它們的 LCS 長度是dp[i][j]。
2.定義base case 讓索引爲 0 的行和列表示空串,dp[0][…]和dp[…][0]都應該初始化爲 0,這就是 base case。
3.找狀態轉移方程:

str1=input("")
str2=input("")
n=len(str1)
m=len(str2)
dp=[None]*(n+1)
for i in range(n+1):
    dp[i]=[0]*(m+1)
dp[0][0]=0
for i in range(1,n+1):
    for j in range(1,m+1):
        if str1[i-1]==str2[j-1]:
            dp[i][j]=dp[i-1][j-1]+1
        else:
            dp[i][j]=max(dp[i-1][j], dp[i][j-1])
print(dp[n][m])

2.最長公共子序列序列
思路:從dp矩陣中最後位置開始遍歷:如果str[i]==str[j]則記錄下當前位置的字符,並前i-1,j-1向前走。如果不相等,則比較dp[i-1][j]與dp[i][j-1] 選擇序列較大的位置進行向前遍歷。

if dp[n][m]==0:
    print(-1)
else:
    lis=[None]*(dp[n][m])
    i=n
    j=m
    k=dp[n][m]-1
    while i>=1 and j>=1:
        if str1[i-1]==str2[j-1]:
            lis[k]=str1[i-1]
            k-=1
            i-=1
            j-=1
        else:
            if dp[i][j-1]>=dp[i-1][j]:
                j=j-1
            elif dp[i][j-1]<dp[i-1][j]:
                i=i-1
    s1=''.join(lis)
    print(s1)

3.將整數N分爲K份,總共有多少種分法? (類似:n個蘋果放入m個盤子有多少種方法)
思路 :因爲每份至少要分1,所以先取K份每份分1,剩下數字(N-K)任意分,可以是分在一份,兩份,…到K份
所以有 D[N,K]=D[D-K][1]+D[D-K][2]+***+D[D-K][K] ①
D[N-1][K-1]=D[(D-1)-(K-1)][1]+***+D[(D-1)-(K-1)][K-1] ②
由①②兩式有:D[N,K]=D[N-1][K-1]+D[D-K][K] (動態轉移方程)
編程如下:

N,K=[int(i) for i in input().split()]
dp=[None]*100
for i in range(100):
    dp[i]=[0]*10
dp[0][0]=1
print(dp)
for i in range(1,  N+1):
    for j in range(1, K+1):
        if i>=j:
            dp[i][j]=dp[i-1][j-1]+dp[i-j][j]
print(dp[N][K])

4.給定一個正整數 n,將其拆分爲至少兩個正整數的和,並使這些整數的乘積最大化。 返回你可以獲得的最大乘積。等價於剪繩子:(劍指offer14題)

 //dp[i]表示:數字 i 拆分爲至少兩個正整數之和的最大乘積
n=int(input(""))
dp = [None]*(n+1)
for i in range(n+1):
    dp[i]=0
#dp[i]表示整數i被拆分可以得到的最大乘積
dp[1] = 1
dp[2] = 1
#i可以被分爲j與i-j
for i in range(3, n+1):
    #j的範圍是1 - i-1
    for j in range(1, i):
        #(i-j)*j不一定是最大乘積,因爲i-j不一定大於dp[i - j]
        dp[i]=max(dp[i], max(dp[i-j]*j, (i-j)*j))
print(dp[n])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章