設乙個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 個數,分別表示...