藍橋杯 算法訓練 最大體積Python實現(揹包,動規)

資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
  每個物品有一定的體積(廢話),不同的物品組合,裝入揹包會戰用一定的總體積。假如每個物品有無限件可用,那麼有些體積是永遠也裝不出來的。爲了儘量裝滿揹包,附中的OIER想要研究一下物品不能裝出的最大體積。題目保證有解,如果是有限解,保證不超過2,000,000,000
  如果是無限解,則輸出0
輸入格式
  第一行一個整數n(n<=10),表示物品的件數
  第2行到N+1行: 每件物品的體積(1<= <=500)
輸出格式
  一個整數ans,表示不能用這些物品得到的最大體積。
樣例輸入
3
3
6
10
樣例輸出
17

分析:
首先看最大公約數,如果最大公約數不是1,那麼肯定無解了,因爲是取最大的取不到的值。直接輸出0.
如果最大公約數是1,且這個數據裏面沒有1(因爲1在數組裏面的話,解爲無窮大,輸出0),我們創建一個用於動規的一維數組,關於數組的長度值得一提,我們知道,最大的取不到的體積肯定不能超過這組數據的最小公倍數,那我們就把最小公倍數設置爲數組的長度,但是跑起來會超時,因爲遞歸求最小公倍數的時候太耗時了,代碼如下:

while True:
    try:
        n = int(input())
        s = []
        for i in range(n):
            s.append(int(input()))
        def lcm(x, y):
            #求最小公倍數
            if x > y:
                greater = x
            else:
                greater = y

            while (True):
                if ((greater % x == 0) and (greater % y == 0)):
                    lcm = greater
                    break
                greater += 1
            return lcm
        temp_1,temp_2=1,1
        #求出所有數的最小公倍數
        for i in range(len(s)):
            temp_1 = lcm(temp_1,s[i])

        #求最大公約數
        def gys(x,y):
            x,y=max(x,y),min(x,y)
            if x%y ==0:
                return y
            else:
                return gys(y,x%y)
        for i in range(len(s)):
            temp_2=gys(temp_2,s[i])

        if temp_2 == 1 and n != 1 and 1 not in s:
            dp = [0 for i in range(temp_1+1)]
            dp[0]=1
            for i in range(len(s)):
                for j in range(s[i],temp_1+1):
                    if dp[j-s[i]]==1:
                        dp[j]=1
            for x in range(temp_1,0,-1):
                if dp[x]==0:
                    print(x)
                    break
        else:
            print(0)
    except:
        break

能過40%。

於是我就直接把數組長度定義爲100000,雖然對於小數據會浪費時間,但是隻要不超時就好。

我們把dp[0]=1:

dp 0 1 2 3 4 5 6 7 8 9 10 15 16 17 18 19 20
dp[] 1 0 0 1 0 0 1 0 0 1 1 1 1 0 1 1 1

關鍵在於dp[x]=1,x是由已知數據組合出來的。

                    if dp[j-s[i]]==1:
                        dp[j]=1

AC代碼:

while True:
    try:
        n = int(input())
        s = []
        for i in range(n):
            s.append(int(input()))
        temp_2=1
        # 求最大公約數
        def gys(x, y):
            x, y = max(x, y), min(x, y)
            if x % y == 0:
                return y
            else:
                return gys(y, x % y)

        for i in range(len(s)):
            temp_2 = gys(temp_2, s[i])

        if temp_2 == 1 and n != 1 and 1 not in s:
            dp = [0 for i in range(100000)]
            dp[0] = 1
            for i in range(len(s)):
                for j in range(s[i], 100000):
                    if dp[j - s[i]] == 1:
                        dp[j] = 1
            for x in range(99999, 0, -1):
                if dp[x] == 0:
                    print(x)
                    break
        else:
            print(0)
    except:
        break

編程小白歡迎指點

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