CSUOJ 1980 不堪重負的數(區間dp)

2022-05-16 05:45:44 字數 1486 閱讀 3127

submit page

summary

time limit: 1 sec     memory limit: 128 mb     submitted: 57     solved: 20    

小x非常喜歡樹,然後他生成了乙個大森林給自己玩。

玩著玩著,小x陷入了沉思。

小x學習了dfs,如果他知道樹的結構,他當然可以很容易地算出樹的負擔值。可是現在沉思中的小x並不知道樹的結構形態,他只知道一棵二叉樹的中序遍歷以及每個節點的價值,那麼這棵二叉樹可能的最小負擔值是多少呢?

第一行為乙個正整數t(t≤20)表示資料組數。

每組資料報括三行。

第一行為乙個正整數n(n≤200)。

第二行為n個正整數wi(wi≤108),表示編號為i的節點的價值。

第三行為n個正整數pi(pi≤n),為乙個1~n的排列,表示二叉樹的中序遍歷結果。

對於每組資料,輸出一行乙個正整數,表示這棵樹可能的最小負擔值。

2

41 2 3 4

1 2 3 4

71 1 1 1 1 1 1

4 2 3 5 7 1 6

18

17

對於第乙個樣例,樹根為3,3的左兒子是2,3的右兒子是4,2的左兒子是1,這樣構成的樹可以達到最小負擔。

對於第二個樣例,對應的滿二叉樹可以達到最小負擔。

2023年8月月賽

devember

解題思路:重點是理解中序遍歷,先左子樹、然後根節點、然後右子樹。找出狀態轉移方程:dp[i][j] = min(dp[i][k-1]+dp[k+1][j]+a[j]-a[i-1],dp[i][j])然後列舉斷點k(也就是根)就行。

做完覺得dp.區間dp和dfs還不太會。。所以重新看了下。想起來之前8月月賽這題剛好就是這個還不會。就做了。。。發現演算法這東西,主要還是理解他的本質基礎,這樣比較容易掌握。。(雖然我還是菜雞- -)

#include#include

#include

using

namespace

std;

const

int maxn=205

;const

long

long inf=1e18;

long

long

a[maxn],w[maxn];

long

long

dp[maxn][maxn];

intmain()

a[0] = 0

; memset(dp,

0,sizeof

(dp));

for(int i=1;i<=n;i++)

for(int l=2;l<=n;l++)}}

printf(

"%lld\n

",dp[1

][n]);

}}

哎。。前面好多演算法都忘了。。當初就理解的不夠透徹。。

打家劫舍(198)

你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你不觸動警報裝置的情況下 一夜之內能夠偷竊到的最高金額。示例 1 輸...

LeetCode 打家劫舍(198)

你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸入 1...

CSU OJ 集訓難度(線段樹)

小l正在組織acm暑假集訓,但眾所周知,暑假集訓的萌新中有oi神犇,也有暑假才開始學演算法的萌新,如果統一集訓的難度,無法很好地讓萌新們得到訓練,所以小l想了乙個辦法,根據每次測試的情況,改變萌新們的集訓難度。現在將萌新們編號為1到n,最初萌新們的集訓難度為v0,測試後有兩種操作,第一種是某一區間的...