記得在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的屬性部分新增一些自定義屬性,位址 列表名稱 要讀取列表專案的數量.下面的是其中乙...