01背包問題-只求背包的最終最大價值,不考慮選哪些物品怎么放---最優解(歡迎討論)


題目來自lintcode

http://www.lintcode.com/zh-cn/problem/backpack/

一個傳統01背包問題的推廣,假如只考一個背包放物品之后的最終最大價值,不考慮具體選哪些物品放入,該如何實現?

最蠢最笨的辦法,那當然就是-老老實實的構造背包容量-物品矩陣,然后取出矩陣最上方最右的值即可:

代碼也非常易懂:

class Solution:
    # @param m: An integer m denotes the size of a backpack
    # @param A: Given n items with size A[i]
    # @return: The maximum size
    def backPack(self, m, A):
        res=[[0 for i in range(len(A)+1)] for j in range(m+1)]
        for i in range(1,m+1):
            for j in range(1,len(A)+1):
                if A[j-1]>i:
                    res[i][j]=res[i][j-1]
                else:
                    res[i][j]=max(res[i][j-1],res[i-A[j-1]][j-1]+A[j-1])
        if len(res)>1:
            res=res[-2:]
        return res[-1][-1]

測試一下:

嗯哼,不炸內存才怪,顯然這種解法,對於這個問題來說浪費太嚴重:

人家只要最終的最大值,不care怎么選,所以實際上只有最頂一行最后一個值是有用的,其他的都不需要。

所以我開始的思路是,就初始化兩個長度為背包容量的數組,來回迭代,最后輸出最后一次迭代的數組的最后一個值

自己改代碼發現失敗,代碼是這么寫的:

於是到群里問了七月的許老師,許老師說給你個C++的解法你改成python吧,她給的C++是這樣:

我改成了python,代碼如下:

class Solution:
    # @param m: An integer m denotes the size of a backpack
    # @param A: Given n items with size A[i]
    # @return: The maximum size
    def backPack(self,m,A):
        can=[False for i in range(m+1)]
        can[0]=True
        big=0
        for i in range(len(A)):
            j=big
            while j>=0:
                if can[j] and j+A[i]<=m:
                    can[j+A[i]]=True
                j-=1
            big+=A[i]
            if big>m:
                big=m
        while can[big]==False:
            big-=1
        return big

嗯哼,牛逼了,3000ms順利AC,但說實話這思路真的還沒搞懂,寫把代碼貼在這兒,回頭研究,歡迎各位博友給點思路,討論一下~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM