NOIP2003提高組第二輪T3:加分二叉樹

題目鏈接

[NOIP2003 提高組] 加分二叉樹

題目描述

設一個 n n n 個節點的二叉樹 tree \text{tree} tree 的中序遍歷為 ( 1 , 2 , 3 , … , n ) (1,2,3,\ldots,n) (1,2,3,,n),其中數字 1 , 2 , 3 , … , n 1,2,3,\ldots,n 1,2,3,,n 為節點編號。每個節點都有一個分數(均為正整數),記第 i i i 個節點的分數為 d i d_i di? tree \text{tree} tree 及它的每個子樹都有一個加分,任一棵子樹 subtree \text{subtree} subtree(也包含 tree \text{tree} tree 本身)的加分計算方法如下:

subtree \text{subtree} subtree 的左子樹的加分 × \times × subtree \text{subtree} subtree 的右子樹的加分 + + + subtree \text{subtree} subtree 的根的分數。

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

試求一棵符合中序遍歷為 ( 1 , 2 , 3 , … , n ) (1,2,3,\ldots,n) (1,2,3,,n) 且加分最高的二叉樹 tree \text{tree} tree。要求輸出

  1. tree \text{tree} tree 的最高加分。

  2. tree \text{tree} tree 的前序遍歷。

輸入格式

1 1 1 1 1 1 個整數 n n n,為節點個數。

2 2 2 n n n 個用空格隔開的整數,為每個節點的分數

輸出格式

1 1 1 1 1 1 個整數,為最高加分( A n s ≤ 4 , 000 , 000 , 000 Ans \le 4,000,000,000 Ans4,000,000,000)。

2 2 2 n n n 個用空格隔開的整數,為該樹的前序遍歷。

樣例 #1

樣例輸入 #1

5
5 7 1 2 10

樣例輸出 #1

145
3 1 2 4 5

提示

數據規模與約定

對于全部的測試點,保證 1 ≤ n < 30 1 \leq n< 30 1n<30,節點的分數是小于 100 100 100 的正整數,答案不超過 4 × 1 0 9 4 \times 10^9 4×109

算法思想

最高加分

根據題目描述:

  • 一棵二叉樹的中序遍歷為 ( 1 , 2 , 3 , … , n ) (1,2,3,\ldots,n) (1,2,3,,n)

在中序遍歷中,一旦確定了根結點,那么左右子樹的節點編號一定在根結點兩側,例如當根節點為 3 3 3時,那么左子樹的結點編號為 1 , 2 1,2 1,2,右子樹的結點編號為 4 , 5 , … , n 4,5,\ldots, n 4,5,,n,如下圖所示:

在這里插入圖片描述

  • 加分計算方法為左子樹的加分 × \times × 右子樹的加分 + + +根的分數。

求一棵符合中序遍歷為 ( 1 , 2 , 3 , … , n ) (1,2,3,\ldots,n) (1,2,3,,n) 且加分最高的二叉樹,就是求以根節點為中心,將左右兩個區間(子樹)合并在一起的最大值,因此可以使用區間型動態規劃進行處理。

狀態表示

f [ i , j ] f[i,j] f[i,j]表示二叉樹中序遍歷的節點編號在區間 [ i , j ] [i,j] [i,j]的最大加分分值。

狀態計算

從最后一個合并位置,也就是根節點的位置可以將狀態計算分為下面幾種情況:

  • 根節點在 i i i位置,此時左子樹為空,加分為 1 × 1\times 1×,得到的分數為 1 × f [ i + 1 ] [ j ] + w [ i ] 1\times f[i+1][j]+w[i] 1×f[i+1][j]+w[i]
  • 根節點在 i + 1 i+1 i+1位置,得到的分數為 f [ i ] [ i ] × f [ i + 2 ] [ j ] + w [ i + 1 ] f[i][i]\times f[i+2][j]+w[i+1] f[i][i]×f[i+2][j]+w[i+1]
  • 根節點在 k k k位置,得到的分數為 f [ i ] [ k ? 1 ] × f [ k + 1 ] [ j ] + w [ k ] f[i][k-1]\times f[k+1][j]+w[k] f[i][k?1]×f[k+1][j]+w[k]
  • 根節點在 j j j位置,此時右子樹為空,加分為 1 × 1\times 1×,得到的分數為 f [ i ] [ j ? 1 ] × 1 + w [ j ] f[i][j-1]\times 1+w[j] f[i][j?1]×1+w[j]

這里 w [ i ] w[i] w[i]表示第 i i i個節點的分數。 f [ i ] [ j ] f[i][j] f[i][j]要取以上情況的最大值。

初始狀態

  • 空樹其加分為 1 1 1,也就是說 f [ i ] [ i ? 1 ] = 1 f[i][i-1]=1 f[i][i?1]=1(或者 f [ i + 1 ] [ i ] = 1 f[i+1][i]=1 f[i+1][i]=1
  • 如果區間只有一個節點,那么分值就是當前節點的分數,即 f [ i ] [ i ] = w [ i ] f[i][i]=w[i] f[i][i]=w[i]

時間復雜度

狀態數為 n × n n\times n n×n,狀態計算需要枚舉根節點的位置 1 1 1 ~ n n n,時間復雜度為 O ( n 3 ) O(n^3) O(n3)

前序遍歷

為了找到最大加分的前序遍歷,就要在區間 [ i , j ] [i,j] [i,j]中找到一個根節點 k k k使得 f [ i ] [ k ? 1 ] × f [ k + 1 ] [ j ] + w [ k ] f[i][k - 1]\times f[k+1][j]+w[k] f[i][k?1]×f[k+1][j]+w[k]等于 f [ i ] [ j ] f[i][j] f[i][j]

對于前序遍歷要先輸出根節點 k k k,然后在遞歸遍歷左子樹( [ i , k ? 1 ] [i,k-1] [i,k?1])和右子樹( [ k + 1 , j ] [k+1,j] [k+1,j])即可。

注意,如果 i i i j j j相等,說明是葉子節點,其子樹的根節點就是自己。

代碼實現

#include <iostream>
using namespace std;
const int N = 50;
int w[N], f[N][N];
int n;
//求區間[i,j]的前序遍歷
void dfs(int i, int j)
{if(i > j) return; //空二叉樹if(i == j) cout << i << " "; //葉子節點else{//枚舉根節點for(int k = i; k <= j; k ++){//如果以k為根節點取得加分最大值if(f[i][j] == f[i][k - 1] * f[k + 1][j] + w[k]) {cout << k << " "; //輸出根節點dfs(i, k - 1); //遞歸遍歷左子樹dfs(k + 1, j); //遞歸遍歷右子樹break;}}}
}int main()
{cin >> n;for(int i = 1; i <= n; i ++) cin >> w[i];//空樹的加分為1for(int i = 1; i <= n + 1; i ++) f[i][i - 1] = 1;//枚舉合并長度for(int len = 1; len <= n; len ++){//枚舉開始位置for(int i = 1; i + len - 1 <= n; i ++){int j = i + len - 1; //結束位置if(len == 1) f[i][i] = w[i]; //初始狀態else{//枚舉其它根節點的位置for(int k = i; k <= j; k ++)f[i][j] = max(f[i][j], f[i][k - 1] * f[k + 1][j] + w[k]);}            }}cout << f[1][n] << '\n';dfs(1, n);return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164401.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164401.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164401.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【視覺SLAM十四講學習筆記】第三講——Eigen庫

專欄系列文章如下&#xff1a; 【視覺SLAM十四講學習筆記】第一講——SLAM介紹 【視覺SLAM十四講學習筆記】第二講——初識SLAM 【視覺SLAM十四講學習筆記】第三講——旋轉矩陣 本章將介紹視覺SLAM的基本問題之一&#xff1a;如何描述剛體在三維空間中的運動&#xff1f; Eigen…

網工內推 | Base北京,國企網工運維,最高30k*14薪,IE認證優先

01 萬方數據股份有限公司 招聘崗位&#xff1a;網絡工程師 職責描述&#xff1a; 1.負責完成基礎網絡組網工作&#xff1b; 2.負責網絡對象的訪問控制及安全策略&#xff0c;配置VLan&#xff0c;黑白名單、地址轉換、故障排查及網絡安全監控工作&#xff1b; 3.負責對操作系…

Vue框架學習筆記——Vue實例中el和data的兩種寫法

文章目錄 前文提要Vue實例的el第一種寫法第二種寫法小結 Vue實例中data第一種寫法&#xff0c;對象式效果圖片第二種寫法&#xff0c;函數式效果圖片小結 前文提要 本文僅做自己的學習記錄&#xff0c;如有錯誤&#xff0c;請多諒解 Vue實例的el 第一種寫法 <body><…

Python圖片文件和base64編碼互轉

圖片和base64編碼互轉 import base64 import cv2# 將圖片base64字符串生成圖片文件. def base64_to_img(base64_code,save_img_path):"""根據base64生成圖片.:param base64_code: 圖片的base64文件:param save_img_path: 生成的圖片路徑:returns: None"&q…

分布式鎖之基于mysql實現分布式鎖(四)

不管是jvm鎖還是mysql鎖&#xff0c;為了保證線程的并發安全&#xff0c;都提供了悲觀獨占排他鎖。所以獨占排他也是分布式鎖的基本要求。 可以利用唯一鍵索引不能重復插入的特點實現。設計表如下&#xff1a; CREATE TABLE tb_lock (id bigint(20) NOT NULL AUTO_INCREMENT,…

(二)C語言之變量與算數運算表達式概述

C語言之變量與算數運算表達式概述 一、華氏溫度與攝氏溫度對照二、代碼概述三、練習 一、華氏溫度與攝氏溫度對照 #include <stdio.h>/*當華氏溫度為 0,20,40,...300時&#xff0c;打印出華氏溫度與攝氏溫度對照表華氏溫度與攝氏溫度 C(5/9)(?F-32) 其中C表示攝氏溫度&…

順序棧和鏈棧

#include<iostream> using namespace std; #define MAXSIZE 100 typedef int SElemType; typedef struct { SElemType* base; SElemType* top; int stacksize; }SqStack;//順序棧 //構造一個空棧 int InitStack(SqStack& s) { s.base new SElemType…

Django之中間件與CSRF_TOKEN

文章目錄 一、什么是中間件二、中間件有什么用三、Django自定義中間件中間件中主要方法及作用創建自定義中間件的步驟&#xff1a;process_request與process_response方法process_view方法process_exceptionprocess_template_response&#xff08;不常用&#xff09; 四、CSRF_…

mysql latin-1報錯解決

conn pymysql.connect(hostmeta_conf[host], usermeta_conf[user], passwordmeta_conf[password], portmeta_conf[port], charsetutf8) 光把表聲明 ENGINEINNODB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin ROW_FORMATDYNAMIC 并不能解決這個報錯,需要在創建mysql連接時候…

面試:RabbitMQ相關問題

文章目錄 簡單介紹RabbitMQRabbitMQ架構什么是 RabbitMQ&#xff1f;有什么顯著的特點&#xff1f;RabbitMQ 有那些基本概念&#xff1f;RabbitMQ routing 路由模式消息怎么路由&#xff1f;RabbitMQ publish/subscribe 發布訂閱(共享資源)能夠在地理上分開的不同數據中心使用 …

vue2指令的使用和自定義指令

前言 個人認為vue的指令,對比react來說,給開發者節省了很大的學習成本。比如在react中,你想渲染一個列表,需要用Array.map的方法return<div>,而在vue中,一個簡單的v-for就解決了問題。 在學習成本和入手體驗上,vue的作者確實后來者居上,能讓人更快的使用vue開發。不過也…

無邊界電視點播TVbox殼+源

TBBox可以是個盒子也可以是軟件 視頻播放的困局新的改變TVBox apk更成熟的熊貓寶盒_3.10還有這個沒測試恒星TV 寫在最后 視頻播放的困局 現在電視上幾大平臺看劇集都要充會員&#xff0c;而電腦上網頁端有很多可以看的網頁&#xff0c;只有 隨便一搜就測出來&#xff0c;只是經…

數據安全第一:應對[[MyFile@waifu.club]].wis勒索病毒的實用建議與技巧

引言&#xff1a; 在當今數字化時代&#xff0c;[[MyFilewaifu.club]].wis、[[backupwaifu.club]].wis勒索病毒是一種惡意軟件&#xff0c;其危害用戶數據安全&#xff0c;通過加密文件并勒索贖金來獲取經濟利益。以下是對[[MyFilewaifu.club]].wis、[[backupwaifu.club]].wis…

PyTorch包

進入PyTorch的官網&#xff1a; pytorch GitHub 點擊GitHub&#xff1a; 進入PyTorch的主目錄&#xff1a; 進入Vision reference&#xff1a; detection&#xff1a; 這就是我們在訓練過程中會使用到的文件了&#xff1a;

objdump反匯編文件解析

命令使用 objdump可以對可執行文件進行反匯編 其常用參數為: objdump -d <file(s)>: 將代碼段反匯編&#xff1b;objdump -S <file(s)>: 將代碼段反匯編的同時&#xff0c;將反匯編代碼與源代碼交替顯示&#xff0c;編譯時需要使用-g參數&#xff0c;即需要調試信…

Hadoop技術與應用的習題

第一章測驗 1、下面哪個選項不屬于Google的三駕馬車&#xff1f; A.HDFS B.MapReduce C.BigTable D.GFS 2、下面哪個思想是為了解決PageRank&#xff08;網頁排名&#xff09;的問題&#xff1f; A.GFS B.BigTable C.MapReduce D.YARN 3、GFS 存儲的文件都被分割成固定大小的…

CAN基礎知識

CAN 簡介 CAN 是 Controller Area Network 的縮寫&#xff08;以下稱為 CAN&#xff09;&#xff0c;是 ISO 國際標準化的串行通信 協議。在當前的汽車產業中&#xff0c;出于對安全性、舒適性、方便性、低公害、低成本的要求&#xff0c;各種 各樣的電子控制系統被開發了出來…

簡單的用Python采集股票數據,保存表格后分析歷史數據

前言 字節跳動如果上市&#xff0c;那么鐘老板將成為我國第一個世界首富 趁著現在還沒上市&#xff0c;咱們提前學習一下用Python分析股票歷史數據&#xff0c;抱住粗大腿坐等起飛~ 好了話不多說&#xff0c;我們直接開始正文 準備工作 環境使用 Python 3.10 解釋器Pychar…

如何應用ChatGPT撰寫、修改論文及工作報告,提供寫作能力及優化工作??

如果我想讓gpt從pdf文檔中提取相關關鍵詞的內容&#xff0c;可以怎么做呢&#xff1f;&#xff1f;我們評論區討論 ChatGPT 在論文寫作與編程方面也具備強大的能力。無論是進行代碼生成、錯誤調試還是解決編程難題&#xff0c;ChatGPT都能為您提供實用且高質量的建議和指導&am…

愛上C語言:scanf、gets以及getchar輸入字符串你真的懂了嗎

&#x1f680; 作者&#xff1a;阿輝不一般 &#x1f680; 你說呢&#xff1a;不服輸的你&#xff0c;他們拿什么贏 &#x1f680; 專欄&#xff1a;愛上C語言 &#x1f680;作圖工具&#xff1a;draw.io(免費開源的作圖網站) 如果覺得文章對你有幫助的話&#xff0c;還請點贊…