合併樹類區間DP

2022-04-30 23:12:20 字數 2235 閱讀 6670

設乙個n個節點的二叉樹tree的中序遍歷為(1,2,3,…,n),其中數字1,2,3,…,n為節點編號。

每個節點都有乙個分數(均為正整數),記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree(也包含tree本身)的加分計算方法如下:     

subtree的左子樹的加分 × subtree的右子樹的加分 + subtree的根的分數 

若某個子樹為空,規定其加分為1。葉子的加分就是葉節點本身的分數,不考慮它的空子樹。

試求一棵符合中序遍歷為(1,2,3,…,n)且加分最高的二叉樹tree。

要求輸出: 

(1)tree的最高加分 

(2)tree的前序遍歷

輸入格式

第1行:乙個整數n,為節點個數。 

第2行:n個用空格隔開的整數,為每個節點的分數(0《分數<100)。

輸出格式

第1行:乙個整數,為最高加分(結果不會超過4,000,000,000)。     

第2行:n個用空格隔開的整數,為該樹的前序遍歷。如果存在多種方案,則輸出字典序最小的方案。

資料範圍

n<30

輸入樣例:

55 7 1 2 10

輸出樣例:

1453 1 2 4 5

思路:

由於是中序遍歷,我們需要找到一棵樹的根節點,根節點就在左子樹和右子樹的中間,所以區間最後一步的劃分就是找到根節點:\(f[1,n]=f[1,k-1]*f[k+1,n]+f[k]\)。由於還需要找到輸出前序遍歷序列,每次dp時把區間的根節點存下來,dfs搜一遍就可以得到了。

#includeusing namespace std;

const int n=40;

long long w[n],f[n][n],root[n][n];

void dfs(int l,int r)

}} }

cout<284. 金字塔

雖然探索金字塔是極其老套的劇情,但是有一隊探險家還是到了某金字塔腳下。

經過多年的研究,科學家對這座金字塔的內部結構已經有所了解。

首先,金字塔由若干房間組成,房間之間連有通道。

如果把房間看作節點,通道看作邊的話,整個金字塔呈現乙個有根樹結構,節點的子樹之間有序,金字塔有唯一的乙個入口通向樹根。

並且,每個房間的牆壁都塗有若干種顏色的一種。

探險隊員打算進一步了解金字塔的結構,為此,他們使用了一種特殊設計的機械人。

這種機械人會從入口進入金字塔,之後對金字塔進行深度優先遍歷。

機械人每進入乙個房間(無論是第一次進入還是返回),都會記錄這個房間的顏色。

最後,機械人會從入口退出金字塔。

顯然,機械人會訪問每個房間至少一次,並且穿越每條通道恰好兩次(兩個方向各一次), 然後,機械人會得到乙個顏色序列。

但是,探險隊員發現這個顏色序列並不能唯一確定金字塔的結構。

現在他們想請你幫助他們計算,對於乙個給定的顏色序列,有多少種可能的結構會得到這個序列。

因為結果可能會非常大,你只需要輸出答案對109 取模之後的值。

輸入格式

輸入僅一行,包含乙個字串s,長度不超過300,表示機械人得到的顏色序列。

輸出格式

輸出乙個整數表示答案。

輸入樣例:

abababa

輸出樣例:

5前序遍歷序列的長度一定是奇數(對於每條邊遍歷一次再加上一開始的根節點\(2*(n-1)+1=2*n-1\)),一顆樹的前序遍歷序列\([l,r],str[l]==str[r]\)是根節點編號,其中的每一棵子樹\([l_i,r_i]\)也都有\(str[l_i]==str[r_i]\)是子樹的根節點,並且要被根節點的編號包裹即:\(str[l_i-1]==str[r_i+1]\)是根節點編號。

當合併乙個區間序列,我們列舉最後一棵子樹的序列區間,所以[l,r]的樹,其最後一棵子樹可以在\([l-1,r-1],[l-2,r-1]...[r-1,r-1]\),不能取到r因為我們是化零為整最後一棵子樹一定不能為空

#includeusing namespace std;

const int n=310,mod=1e9;

char str[n];

long long f[n][n];

int main()}}

}}

cout

}

石子合併 (區間DP

問題描述 在乙個操場上擺放著一行共n堆的石子。現要將石子有序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆石子數記為該次合併的得分。請編輯計算出將n堆石子合併成一堆的最小得分和將n堆石子合併成一堆的最大得分。輸入檔案 輸入第一行為n n 1000 表示有n堆石子,第二行為n個用空...

石子合併 區間dp

有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。假設dp 1 4 表示將區間1 4的石子合併所花費的代價。dp 1 4 可以劃分為dp 1 1 dp 2...

石子合併 (區間DP)

題目鏈結 描述 有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。輸入第一行有乙個整數n,表示有n堆石子。接下來的一行有n 0 n 200 個數,分別表示...