乙個糾結了我N久的 數集劃分問題

2021-06-16 04:15:27 字數 1167 閱讀 1306

記得在toj上曾經有一道題,大致意思如下:

將2n個整數平均分為兩堆,每堆n個,使得兩堆和的差值最小,求這個差值。

當時自己很自豪的用「隨機貪心」的思想寫出來的程式在oj上居top1,(44k 0ms)

看著一大堆用dp ac的選手們幾百k的記憶體使用量+幾十毫秒的計算速度,小得意了一把。

該隨機貪心思想如下:

1 將2n個數隨意分為兩堆,稱為a、b。

2 若存在 a in a,b in b,交換a、b使得sum(a) 與 sum(b)差值更小,則交換。

3 若2不存在,跳出,否則重複2

4 得到最小 sum差

之後我自己想了一下,假如題目改為這樣呢?——

將n個整數分為兩堆,每堆個數不固定,使得兩堆和差值最小,求這個差值。

然後我和n個同學討論了這個問題。。未果,最後得出結論:這是乙個np問題……

我還是用隨機貪心可以得出乙個近似解——

0 r=正無窮

1 將n個數隨機分為兩堆,a、b

2 若存在a in a或者b in b,將a,b放到另乙個集合中,能使得sum(a) 與 sum(b)差值更小,則調換。

3 若2不存在,跳出,否則重複2

4 得到單次最小 sum差k,若比sum差r小,則r = k

5 隨機次數++

6 若隨機次數》n(這個值越高,越趨近正確解)結束,輸出r

7 跳到1

看上去覺得不錯了,而且理論上n越大,解就越趨近正確。

我一度認為這就是乙個好的解法。。直到同學wl提出來有更優解法……

1 將n個數排序,稱集合a

2 取出a中最大兩個數a,b,相減得c

3 a,b出集合,c進集合

4 若a只有乙個元素跳出,否則跳到2

5 a中最後乙個元素就是正確解

我靠~ 想了想,確實,這個問題居然就能用乙個普通的貪心演算法解決……

歸根到底還是乙個數學問題,若不平均劃分,則可以這樣「等價消除」各數字。(此處證明略,很顯然……)

所以看來未必看上去"牛x"的演算法就牛x,一切演算法問題還是應該歸根於其數學本質上的。

——時刻用這句話警誡自己!已經在此問題上犯了無數次錯誤了。

ps:該問題我曾出題到公司的天津大學/南開大學校園招聘筆試題上,當場給出第一題近似解的只有一位碩士生。。第二題沒人做。。(可能時間不夠)

糾結我的乙個DataTime型別

因為這個原因 改錯,然後看了一些其他人的資料 引用 做乙個專案時,有個日期字段客戶可輸入可不輸入值,直接把datetime null時會出錯,提示錯誤 無法將 null 轉換成 system.datetime 因為它是一種值型別 在網上檢視下相關資料後,找到處理辦法 nullable now dat...

oracle板塊的乙個帖子小糾結了一下

帖子內容 表 字段 name id aaa 1,2,3 bbb 1,2 結果 name id aaa 1 aaa 2 aaa 3 bbb 1 bbb 2 蘭蘭 select name,regexp substr id,1,n from test a left join select level ro...

sharepoint 糾結的乙個小問題

遇到乙個小小的問題,糾結了半天,記錄一下。做了乙個小webpart,很小很簡單的乙個功能,讀取列表然後在前台顯示出來,剛得到需求時很不屑.報應就是浪費了我半天的時間.因為要讀取的列表位置不固定,所以需要在webpart的屬性部分新增一些自定義屬性,位址 列表名稱 要讀取列表專案的數量.下面的是其中乙...