编程笔试题※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])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章