1. 程式人生 > >Stone Pile

Stone Pile

nta HA 元素 定義函數 無奈 body urn () problem

Problem

  You have a number of stones with known weights w 1, …, wn. Write a program that will rearrange the stones into two piles such that weight difference between the piles is minimal.

Input

  Input contains the number of stones n (1 ≤ n ≤ 20) and weights of the stones w 1, …, wn (integers, 1 ≤ wi
≤ 100000) delimited by white spaces.

Output

  Your program should output a number representing the minimal possible weight difference between stone piles.

Example

inputoutput
5
5 8 13 27 14
3
題目大意   給出一坨重量不定的石頭,將其分成兩份使得其重量差值最小。 題目解讀   石頭總數很少,重量偏大(也不是十分大)。 算法   設所有石頭總重量為 S,要使兩份石頭重量差值最小,換句話說就是讓每一份石頭的重量都盡量接近 S / 2。   考慮一個容量為 ?S / 2? 的背包,用石頭把這個背包盡量填滿,此時將所有石頭以是否在背包中為標準,分成兩堆,這兩堆石頭重量差值即為題目所求解。   直接套用 0-1 背包,f[i] = max{f[i - w[j]] + w[j]},時間復雜度 O(nS)。 代碼
 1 n = int(input())
 2 w = input().split()
 3 for i in range(n):
 4     w[i] = int(w[i])
 5 s = sum(w)
 6 m = s - s // 2
 7 f = [0 for i in range(m + 1)]
 8 for i in range(n):
 9     for j in range(m, w[i] - 1, -1):
10         f[j] = max(f[j], f[j - w[i]] + w[i])
11 print(abs(s - f[m] * 2))

算法 2
  本來想用背包直接偷雞,實際上上述算法也是足夠快的,但無奈 Python 速度實在無法與 C++ 相比。   老老實實改用搜索,時間復雜度 O(2n),保險起見排了個序加了個可行性剪枝。 代碼 2
n = int(input())
w = input().split()

def dfs(now, size):
    if ((now == n) or (size < w[now])):
        return size;
    return min(dfs(now + 1, size - w[now]), dfs(now + 1, size))


for i in range(n):
    w[i] = int(w[i])
w.sort()
s = sum(w)
m = s - s // 2
print(abs(s - (m - dfs(0, m)) * 2))

代碼解讀

  註意:以下內容完全根據筆者自己對 Python 3 的理解胡說八道。

  sum():求和函數,返回列表所有元素的和。

  max():最大值函數,返回若幹個數(或列表)中最大的元素。

  abs():絕對值函數,返回一個數的絕對值。

  def:定義函數(?)。

  min():最小值函數,返回若幹個數(或列表)中最小的元素。

  sort():排序函數,默認將列表元素按升序排序。

Stone Pile