關於最大加權集求解問題的思路(歡迎大家糾正)

2021-07-07 03:07:41 字數 1537 閱讀 3830

對於集合,相信大家都不陌生。

對於集合中的每個元素,如果我們賦予它乙個數值,這個數值就代表它的權重。假設乙個菜市場是乙個集合,那個我們可以認為,青菜、蘿蔔、豬肉、魚是這個集合的元素,這個集合記作s=;現在我們給這個集合中的每個元素標上**,青菜:1元一斤,蘿蔔:兩元一斤,豬肉:13元一斤,魚:10元一斤,那麼,我們可以認為這些元素的**就是它們的權重,這就是權重的意義。那什麼是最大加權集呢?假設現在我們去菜市場,需要購買一種蔬菜和一種葷菜。毫無疑問,在這個集合中,我們有四種選擇,分別是:青菜豬肉,青菜魚,蘿蔔豬肉,蘿蔔魚,可以很容易看出其中最貴的是蘿蔔豬肉。這裡的就是這個集合對於一葷一素的最大加權集。

很顯然的是,當我們的集合中的元素很大時,求集合的最大加權集問題是np-難的。在這裡,我們討論的就是求乙個集合最大加權集的思路。

對於以上的集合,我們可以一眼就看出它的最大加權集,然而對於我們的計算機,它的計算過程並非如此簡單,它需要把乙個個的可能性都列出來,然後進行比較,最後才能得出最大。當集合足夠的,人一眼都看不出答案時,對計算機也是一種考驗,所以需要對計算機的演算法進行優化。

我們以以上的集合為列,第一步,我們將要構建乙個衝突圖,何為衝突?何為衝突圖?在我們要買一葷一素的前提下,青菜和蘿蔔即是衝突的,豬肉和魚也是衝突的。所謂衝突圖,就上將他們的衝突關係表現在乙個二維圖示上,用1表示衝突,0表示不衝突,如下:

演算法是這樣的:設opt(u)表示u的最大加權集,val(u)表示u中所有元素的權重和

opt(s)=

val()>val(opt(s-青菜)):(s-青菜)                     

(此表示式為c語言中的表示式)

此時(

s-所有與青菜衝突的元素(包括本身)) =

(s-青菜) =

以此遞迴下去,直到集合為空集。

opt() = val()>val()--至此集合為空,返回豬肉

opt = val(})> val(opt)?} : opt

opt() = val()

>

val() ?

: --至此集合為空,返回豬肉

此時遞迴一層層返回:

①豬肉 > 魚 return 豬肉;

②蘿蔔,豬肉 > 豬肉 return 蘿蔔,豬肉;

③青菜,豬肉 > 蘿蔔,豬肉 return 青菜,豬肉;

這是顯而易見的。

以此演算法,當集合中元素的數量很客觀時,能很好地計算出最大加權集,其**如下:

在此演算法中,我沒有計算其時間複雜性和空間複雜性,不過應該是很客觀的,有興趣的朋友可以試著算算。

關於加權的LIS問題

蒟蒻zigzag正在準備聯賽.這個算是這幾天做的唯一乙個值得寫一寫的題吧。首先lis的n 2暴力dp應該都會寫,就是f i max 1 那麼加權的就吧後面的1換成數的權值就行了,如果優先長度的話加一些判斷就行了。那麼o nlogn 怎麼寫?lis的nlogn應該都會寫,就是記乙個陣列d i 表示長度...

關於求解p x mod q的問題

如題,其中p和q都是素數,而x是數值十分大的合數,則p x mod q的一種解法可為 第一步,可把x寫成a b的形式,即p x p a b,其中p a是可以通過簡單的人為計算得出的並且滿足p a q,設c p a,則p x通過降次得到c b 第二步,把c展開,寫成c dq e的形式,則c b dq ...

最大子串行和問題的求解

問題描述 給定 可能存在負值 整數a1,a 2.a n,求最大子串行和。如果所有的整數均為負數,則最大子串行和為0.列如 對於輸入 2,11,4,13,5,2,該輸入的最大子串行和為20 11 4 13 現在我們將敘述四個演算法來求解最大子串行和問題。1.該演算法是使用窮舉法來嘗試所有的可能 演算法...