洛谷P2515 HAOI2010 軟體安裝

2022-03-17 17:06:41 字數 3458 閱讀 9240

現在我們的手頭有n個軟體,對於乙個軟體i,它要占用wi的磁碟空間,它的價值為vi。我們希望從中選擇一些軟體安裝到一台磁碟容量為m計算機上,使得這些軟體的價值盡可能大(即vi的和最大)。

但是現在有個問題:軟體之間存在依賴關係,即軟體i只有在安裝了軟體j(包括軟體j的直接或間接依賴)的情況下才能正確工作(軟體i依賴軟體j)。幸運的是,乙個軟體最多依賴另外乙個軟體。如果乙個軟體不能正常工作,那麼它能夠發揮的作用為0。

我們現在知道了軟體之間的依賴關係:軟體i依賴軟體di。現在請你設計出一種方案,安裝價值盡量大的軟體。乙個軟體只能被安裝一次,如果乙個軟體沒有依賴則di=0,這時只要這個軟體安裝了,它就能正常工作。

輸入格式:

第1行:n, m (0<=n<=100, 0<=m<=500)

第2行:w1, w2, ... wi, ..., wn (0<=wi<=m )

第3行:v1, v2, ..., vi, ..., vn (0<=vi<=1000 )

第4行:d1, d2, ..., di, ..., dn (0<=di<=n, di≠i )

輸出格式:

乙個整數,代表最大價值

輸入樣例#1

3 10
5 5 6
2 3 4
0 1 1

輸出樣例#1

5

演算法:

樹形dp

分析:

一看到這道題,就感覺和選課很相似,不過再仔細一看,就發現其實之間大有不同。

選課一題,是不可以成環的,因為先修課的先修課不可能成為後面的後修課,所以,判環是沒必要的。

但是這道題,非常坑爹,它可以出現環。若出現a依賴b,b依賴c,c依賴a,那麼我們究竟怎麼搜尋呢,而且轉移方程也不好寫。

我們通過觀察發現,這種環狀的問題,要是選了其中乙個,那麼就意味著要把整個環給選了,要麼不選,就得整個都不選。

所以,我們就可以從這裡入手,把乙個個的環縮成乙個個新的點,乙個點代表了環的整體。

接下來就可以通過選課的後續思路,建造一棵左兒子右兄弟的二叉樹,通過多叉樹轉二叉樹進行記憶化搜尋。

後面的就很簡單了,狀態轉移方程就是要不要當前的兄弟,還是把機會分給兄弟和孩子。

不過中途有很多小點需要注意。

判環要用floyed的方法三重for來判斷環,記得三個迴圈的變數順序不能錯,否則後果會判不到環。

其次,縮點建點的時候,主體分三個情況來判斷:

1、這是新環,我需要建點來記錄,他的價值和體積我都直接相加就好了。不過我們要記得把已經轉移的新點的原來兩個舊點序號變成負數,而新點的下標+舊點的內容恰好是等於n的,每乙個環一一對應,不多也不會少,詳情見**操作。

2、這是舊環,我發現了新的點,這個點在環內。那麼我就把這個點並到環中,把價值和體積也加到新點上,然後把原來這個舊環的密碼推到這個新點上。

3、找到乙個新點,他和乙個舊環有聯絡,但不屬於這個環的一部分,於是把它的從屬關係推到新的點上。

步驟簡化為:判環+縮點+多叉轉二叉+記憶化搜尋。

上**:

1 #include2 #include3 #include4

using

namespace

std;56

const

int size=600;7

int n,m,ans,sum,d[size],v[size],w[size],f[size][4*size],b[size],c[size];

8bool a[size][size]; //

是否連通

910 inline int read() //

讀入優化

1120

21void floyed() //

floyd判環

2230

31void connect() //

縮點建點

3246

else

47if (w[d[j]]<0&&w[j]>0) //

發現舊環

4855

else

//不屬於環

56if (a[d[j]][j]&&!a[j][d[j]]||!a[d[j]][j]&&a[j][d[j]])

57 d[j]=n-w[d[j]];58}

59}60}

6162

int dfs(int root,int val) //

記憶化搜尋

6377

return

f[root][val];78}

7980

intmain()

8194

floyed();

95connect();

96for (i=1;i<=ans;i++) //

模擬鍊錶

97if (w[i]>0)98

102 printf("

%d",dfs(c[0

],m));

103return0;

104 }

這道題其實難度很大,不過只要把原理弄懂,**還是很好打的,主要就是圍繞著如何更加簡便地進行記憶化搜尋,然後一層層地進行優化,這道題用到的就是判環和縮點的知識。

嗯,就這樣了。

洛谷 P2515 HAOI2010 軟體安裝

現在我們的手頭有n個軟體,對於乙個軟體i,它要占用wi的磁碟空間,它的價值為vi。我們希望從中選擇一些軟體安裝到一台磁碟容量為m計算機上,使得這些軟體的價值盡可能大 即vi的和最大 但是現在有個問題 軟體之間存在依賴關係,即軟體i只有在安裝了軟體j 包括軟體j的直接或間接依賴 的情況下才能正確工作 ...

P2515 HAOI2010 軟體安裝

傻了。思路 scc 縮點,樹上揹包。提交 2次 無語。建邊建錯了 思路 關係可能會形成環,而整個環是乙個整體 要選就選環上所有點,否則整個不選 所以我們先把所有的環縮點,然後便形成了一棵樹 乙個點不可能有兩個父親 然後跑樹上揹包。include include using namespace std...

P2515 HAOI2010 軟體安裝

現在我們的手頭有n個軟體,對於乙個軟體i,它要占用wi的磁碟空間,它的價值為vi。我們希望從中選擇一些軟體安裝到一台磁碟容量為m計算機上,使得這些軟體的價值盡可能大 即vi的和最大 但是現在有個問題 軟體之間存在依賴關係,即軟體i只有在安裝了軟體j 包括軟體j的直接或間接依賴 的情況下才能正確工作 ...