zoukankan      html  css  js  c++  java
  • 洛谷 P1040 加分二叉树 & [NOIP2003提高组](区间dp,树的遍历)

    传送门


    解题思路

    对于整个中序遍历,做一遍区间dp:

    枚举区间[l...r]内的所有节点作为根节点,然后计算出得分,若比当前的值要大,同时更新dp值和root[l][r](为了输出先序遍历)。

    先序是根左右,所以递归输出就好了。

    AC代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 int n,a[35],dp[35][35],root[35][35];
     6 void print(int l,int r){ 
     7     if(l>r) return;
     8     if(l==r) printf("%d ",l);
     9     else{
    10         printf("%d ",root[l][r]);
    11         print(l,root[l][r]-1);
    12         print(root[l][r]+1,r);
    13     }
    14 }
    15 int main()
    16 {
    17     cin>>n;
    18     for(int i=1;i<=n;i++) cin>>a[i];
    19     for(int i=1;i<=n;i++) dp[i][i]=a[i];
    20     for(int i=1;i<=n;i++){
    21         for(int j=0;j<i;j++) dp[i][j]=1;
    22     }
    23     for(int len=2;len<=n;len++){
    24         for(int i=1;i<=n;i++){
    25             int j=i+len-1;
    26             for(int k=i;k<=j;k++){
    27                 if(dp[i][j]<dp[i][k-1]*dp[k+1][j]+a[k]){
    28                     dp[i][j]=dp[i][k-1]*dp[k+1][j]+a[k];
    29                     root[i][j]=k;
    30                 }
    31             }
    32         }
    33     }
    34     cout<<dp[1][n]<<endl;
    35     print(1,n);
    36     return 0;
    37 }

    //NOIP2003提高组 t3

  • 相关阅读:
    HDU 4268 multiset
    ACM-线段树
    HDU 5014 异或之和
    HDU 5012 骰子旋转(DFS)
    HDU 5011 NIM博弈
    HDU 5007 字符串匹配
    Android-Context
    Android-视图绘制
    Android-LayoutInflater
    oracle--分页过程demo1
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12358357.html
Copyright © 2011-2022 走看看