説明のタイトル
番号1,2,3、...、nはノードの数であり、(1,2,3、...、n)とプレオーダーにおけるN個のノードのバイナリツリーを提供しました。各ノードはフラクションDIノード、各サブツリーi番目呼ばスコア(正の整数の両方)を有し、それはプラスツリーを有し、任意のサブツリーサブツリーが(も含むツリー自体)プラス:次のように分が計算され
、プラス左右のサブツリーサブツリーのサブツリープラスサブツリー+留分の根の×サブツリー。
サブツリーが空である場合、そのプラス1分割葉スコア余分なポイントの規定は、リーフノード自体です。その空の木のに関わらず。
予約購入が(1,2,3、...、N)に準拠して決定し、バイナリツリーの最高点。必要な出力は、
(1)ツリーが最高点
(2)プリアンブルツリートラバーサルの
入力と出力形式
の入力フォーマット:
1行目:整数N(N <30)、ノードの数です。
行2:スペースで区切られたNNN整数、分数として各ノード(画分<100)。
出力フォーマット:
1行目:整数、最高点(ANS≤4,000,000,000)。
2行目:nはツリーの先行順走査のために、スペースで区切られた整数。
サンプル入力出力
入力サンプル#1:
5
。5。7 1 2 10
出力サンプル#1:
145
。3 1 2 4 5
説明:私たちは、それぞれの子のルートノードを列挙することができ、そして暴力が最適解はそれを列挙メモリで見つけることができる計算するので、我々はDP [L] [j]は、Rツリーへリットルから最大のコンストラクタで定義しますOKに記録処理中に計算された値、
#include<iostream>
#define N 35
using namespace std;
long long dp[N][N]={0};
int pre[N][N]={0};
long long a[N]={0};
int n=0;
long long dfs(int l,int r,int fal,int far){
if(r<l){
if(fal==far) return 0;
else return 1;
}
if(dp[l][r]) return dp[l][r];
for(int mid=l;mid<=r;mid++){
long long A=dfs(l,mid-1,l,r),B=dfs(mid+1,r,l,r);
if(a[mid]+A*B>dp[l][r]){
dp[l][r]=a[mid]+A*B;
pre[l][r]=mid;
}
}
return dp[l][r];
}
void print(int l,int r){
int mid=pre[l][r];
if(r<l) return;
cout<<mid<<" ";
print(l,mid-1);
print(mid+1,r);
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
dfs(1,n,1,n);
cout<<dp[1][n]<<endl;
print(1,n);
return 0;
}