打牌博弈 dfs深度優先遍歷搜索 排課表 拓撲排序 升序字符串 動態規劃 劍指offer編程題整理 leetcode每日算法題

遞歸,回溯, 深度優先搜索

題目描述

有一疊撲克牌,每張牌介於1和10之間
有四種出牌方法:

單出1張
出2張對子
出五張順子,如12345
出三連對子,如112233

給10個數,表示1-10每種牌有幾張,問最少要多少次能出完

https://blog.csdn.net/m0_38065572/article/details/105019514


def dfs(l):
    if tuple(l) in memo:
        return memo[tuple(state)]
    if sum(l)==0:
        return 0
    else:
        res = float('inf')
        
        for i in range(10):
            if i<=5 and l[i]>=1 and l[i+1]>=1 and l[i+2]>=1 and l[i+3]>=1 and l[i+4]>=1:
                l[i:i+5]=[l[i+k]-1 for k in range(5)]
                res = min(res, dfs(l)+1)
                l[i:i+5]=[l[i+k]+1 for k in range(5)]
                memo[tuple(state)] = res
            if i<=7 and l[i]>=2 and l[i+1]>=2 and l[i+2]>=2:
                l[i:i+3]=[l[i+k]-1 for k in range(3)]
                res = min(res, dfs(l)+1)
                l[i:i+3]=[l[i+k]+1 for k in range(3)]
                memo[tuple(state)] = res
            if l[i]>=2:
                l[i]=l[i]-2
                res = min(res, dfs(l)+1)
                l[i]=l[i]+2
                memo[tuple(state)] = res
            if l[i]>=1:
                l[i]=l[i]-1
                res = min(res, dfs(l)+1)
                l[i]=l[i]+1
                memo[tuple(state)] = res
        return res
        
def input():
    l= '1 1 2 2 2 1 1 0 0 0'
    return l

memo={}
state= list(map(int,input().split()))
print(state)
print(dfs(state))

 

題目描述

首先定義上升字符串,對於任意的0<i<len(s)0<i<len(s)0<i<len(s),s[i]≥s[i−1],比如aaa,abc是,acbd不是
給n個上升字符串,選擇任意個拼起來,問能拼出來的最長上升字符串長度

https://blog.csdn.net/m0_38065572/article/details/105019514

這個題目很類似於一個經典的題目,課表安排的問題,課表安排的問題可以使用動態規劃,或貪心。

到j的最長長度是dpj

到j-1的最長長度dpj-1  和 到i的最長長度dpi+Sij 中間 較大的一個

動態規劃問題可以用遞歸回溯,也可以記錄每一步狀態(這道題目中狀態是以字符‘j’結尾的最長長度)

 


def longestAscString(strs:List[str])-> int:
    strs=sorted(strs,key=lambda x:(x[-1],x[0])) #尾字符升序,第二關鍵字爲首字符升
    dp=[0]*26 #記錄以字符j結尾的最長長度
    res=0# 記錄全局最優
    
    last=0
    for string in strs:
        begin=ord(string[0])-ord('a')
        end=ord(string[-1])-ord('a')
        for i in range(last,end): 
            # 沒有這些字符結尾的最長長度,使用前面的最長長度更新
            dp[i+1]=dp[last]
        dp[end]=max(dp[end],dp[begin]+len(string))#dp遞推公式,從記錄的上一步全局最有值,推到下一步全局最優
        res=max(res,dp[end])
        last=end

    return res

a=[
    "bcdefhijk",
    "bcd",
    "aaa",
    "eeeefghhh",
    "zzzz",
]
b=['abc',
'hpq',
'qrt',
'jklmnopqr',
'abcjklmnopqr',]

c=['abcd',
'deft',
'efghmnt',
'defghjkl',
'abcddefghjkl',]
print(longestAscString(c))


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章