蓝桥杯节点选择(java)第一道树形dp分析
藍(lán)橋杯 節(jié)點(diǎn)選擇
問(wèn)題描述
有一棵 n 個(gè)節(jié)點(diǎn)的樹(shù),樹(shù)上每個(gè)節(jié)點(diǎn)都有一個(gè)正整數(shù)權(quán)值。如果一個(gè)點(diǎn)被選擇了,那么在樹(shù)上和它相鄰的點(diǎn)都不能被選擇。求選出的點(diǎn)的權(quán)值和最大是多少?
輸入格式
第一行包含一個(gè)整數(shù) n 。
接下來(lái)的一行包含 n 個(gè)正整數(shù),第 i 個(gè)正整數(shù)代表點(diǎn) i 的權(quán)值。
接下來(lái)一共 n-1 行,每行描述樹(shù)上的一條邊。
輸出格式
輸出一個(gè)整數(shù),代表選出的點(diǎn)的權(quán)值和的最大值。
樣例輸入
5
1 2 3 4 5
1 2
1 3
2 4
2 5
樣例輸出
12
樣例說(shuō)明
選擇3、4、5號(hào)點(diǎn),權(quán)值和為 3 4 5 = 12 。
數(shù)據(jù)規(guī)模與約定
對(duì)于20%的數(shù)據(jù), n <= 20。
對(duì)于50%的數(shù)據(jù), n <= 1000。
對(duì)于100%的數(shù)據(jù), n <= 100000。
權(quán)值均為不超過(guò)1000的正整數(shù)。
分析
- 看到藍(lán)橋杯的樹(shù)形dp題,剛開(kāi)始看的很蒙蔽。從來(lái)沒(méi)做過(guò)樹(shù)形的dp,剛開(kāi)始表示很難理解,當(dāng)時(shí)主要的疑惑點(diǎn)有一下幾點(diǎn):
1:這個(gè)樹(shù)怎么解決?這么亂的一棵樹(shù)感覺(jué)根本無(wú)法下手,因?yàn)槟悴恢滥莻€(gè)是根節(jié)點(diǎn),那個(gè)是子節(jié)點(diǎn)。輸出的結(jié)果又和那個(gè)有關(guān)系?
2:樹(shù)形怎么dp?以前都是遇到線(xiàn)性區(qū)間的dp,樹(shù)形dp,怎么查找連續(xù)點(diǎn),就算找到連續(xù)的點(diǎn)交叉點(diǎn)如何處理? - 看了一些博客和文章之后,有了解到dp處理樹(shù)形的特殊手段:
一: 一般來(lái)說(shuō),樹(shù)形dp的每個(gè)節(jié)點(diǎn)都有一個(gè)選擇性,本題就是該店選擇和不選擇,dp[i][0]表示不選擇,dp[i][1]表示選擇該節(jié)點(diǎn)。
二:對(duì)于樹(shù)形dp,一般要和搜索結(jié)合(更確切的說(shuō)是遞歸)結(jié)合,對(duì)于樹(shù)的劃分層次,一般是選擇一個(gè)點(diǎn),然后從這個(gè)點(diǎn)進(jìn)行往下搜索 ,他的鄰居都變成他的子節(jié)點(diǎn)。也就是相當(dāng)于從這個(gè)根節(jié)點(diǎn)除法,可能有很多分叉。也就是有很多分叉會(huì)到根節(jié)點(diǎn)。但是這有和dp有啥關(guān)系呢?dp是從尾到頭還是從頭到尾?
三:對(duì)于順序的選擇肯定是從尾部到頂部,因?yàn)閐p要的是一個(gè)整合結(jié)果而不是分散求最值或者其他。那么還有問(wèn)題就是那么多的跟節(jié)點(diǎn),那么多合的點(diǎn),還有反向路徑不好記錄,記錄的難度和開(kāi)銷(xiāo)都超級(jí)大。如果從尾部推到dp還是有一定難度。
四:我們要先拋開(kāi)整體看局部這個(gè)點(diǎn),對(duì)于某個(gè)單點(diǎn)來(lái)說(shuō)(如果他是頭節(jié)點(diǎn)),分析到他的結(jié)果,如果取他那么他的兒子們都不能取,那么dp[i][1]=dp[兒子們][0] value[i];如果不取他,那么對(duì)于每個(gè)兒子來(lái)說(shuō)要給最大的,那么dp[i][0]=max(dp[每個(gè)兒子][0],dp[每個(gè)兒子][1]);這樣就得到遞推式dp[x][0]=sum(max(dp[num][0],dp[num][1]));dp[x][1]=sum(dp[num][0]) value[i].
五:對(duì)于頭節(jié)點(diǎn)(可以任選),滿(mǎn)足④,對(duì)于頭節(jié)點(diǎn)的兒子也同樣滿(mǎn)足④,但是唯一不同的是要過(guò)濾頭節(jié)點(diǎn)(準(zhǔn)確的說(shuō)是父節(jié)點(diǎn))。防止死循環(huán)。遞歸搜索的過(guò)程是雙向的過(guò)程,先去再回,我們可以同過(guò)先去構(gòu)造樹(shù)并且獲得后面的一些信息,然后根據(jù)后來(lái)得到的值進(jìn)行操作當(dāng)前等級(jí)的dp。 - 總的來(lái)說(shuō)這個(gè)樹(shù)形dp就是分析某個(gè)點(diǎn)的狀態(tài)方程,通過(guò)遞歸搜索進(jìn)行劃分樹(shù)。獲得結(jié)果。并且這題只有n-1條路徑,n個(gè)點(diǎn),不用考慮去重。
附上代碼:
但是結(jié)果只能過(guò)7個(gè),
看了下其他人沒(méi)優(yōu)化輸入的只能過(guò)5個(gè)超時(shí)。我用測(cè)試數(shù)據(jù)測(cè)試了一下原因是棧內(nèi)存溢出。苦逼的Java。。
也可能是因?yàn)槲冶容^菜,,想不出好的方法,呵呵,。歡迎大佬踢場(chǎng)。。
總結(jié)
以上是生活随笔為你收集整理的蓝桥杯节点选择(java)第一道树形dp分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 蓝桥杯最短路(java过)spfa单源最
- 下一篇: 前后台分离使用cookie判断用户状态以