【藍橋杯】第十二屆藍橋杯砝碼稱重(Python題解)


@

題目 【80分】

你有一架天平和N個砝碼,這N個砝碼重量依次是W1,W2,……,WN請你計算一共可以稱出多少種不同的重量?
注意砝碼可以放在天平兩邊。

【樣例輸入】
3
1 4 6
【樣例輸出】
10

思路

這是一道動態規划題

  1. 確定dp數組(dp table)以及下標的含義
  2. 確定遞推公式
  3. dp數組如何初始化
  4. 確定遍歷順序
  5. 舉例推導dp數組

知識點

將dp初始化為0,二維數組
對於第一個加入的dp[i][array[0]]=1標記為能稱出的重量
image

最終dp:
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
第一次加入1,所以在dp[0,1] 這里標記為1

[0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0]
第二次加入4,所以在dp[1][4] 這里標記為1,之前的狀態為dp[0][1]也是為1,之后在加入4之后;4+1=5,所以dp[1][5]標記為1,abs(1-4)==3,所以dp[1][3]也標記為1;
[0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]
同理:
所以最后求解個數的時候只需要將求解dp數組最后一行有多少個1,也就能得出答案
思路是沒問題,不過這道題最后兩個測試樣例超時了只有80分

代碼


n = int(input())
array = list(map(int, input().split()))

sum = sum(array)
a_len = len(array)
ans = 0
dp = [[0 for i in range(sum+1)] for j in range(a_len)]

dp[0][array[0]]=1 # no1

for i in range(1,a_len):
    for j in range(1,sum+1):
        dp[i][j]=dp[i-1][j] # copy 對於當前的復制前一個的重量
    dp[i][array[i]]=1 # 當前狀態是可稱的
    for j in range(1, sum+1): # 最大重量為所有砝碼重量總和
        if(dp[i-1][j]): #pre=1 上一個狀態的重量
            dp[i][j+array[i]] = 1 # 上一狀態的重量在加上當前重量
            dp[i][abs(j-array[i])]=1 # 上一個狀態的重量減去當前狀態的重量

for i in range(1,sum+1):
    if(dp[n-1][i]):
        ans += 1

print(ans)


image


免責聲明!

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



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