zoukankan      html  css  js  c++  java
  • [NOIP2003]加分二叉树

    嘟嘟嘟

    中序遍历有一个特点:序列[1, n]是一个中序遍历,i 是根节点,则[1, i - 1]是他的左子树的中序遍历,[i + 1, n]为右子树的中序遍历。所以就想到了区间dp,对于[i, j]枚举根节点k,则dp[i][j] = max(dp[i][k - 1] * dp[k + 1][j] + a[k])。初始化dp[i][i] = a[i],又因为空节点为1,所以dp[i][i - 1] = 1。

    前序遍历的话就再开一个二维数组f[i][j]存这个区间所属哪一个节点,输出的时候跟区间dp很像,具体看代码吧。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 35;
    21 inline ll read()
    22 {
    23   ll ans = 0;
    24   char ch = getchar(), last = ' ';
    25   while(!isdigit(ch)) {last = ch; ch = getchar();}
    26   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    27   if(last == '-') ans = -ans;
    28   return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32   if(x < 0) x = -x, putchar('-');
    33   if(x >= 10) write(x / 10);
    34   putchar(x % 10 + '0');
    35 }
    36 
    37 int n, a[maxn];
    38 ll dp[maxn][maxn];
    39 int f[maxn][maxn];
    40 
    41 void print(int L, int R)
    42 {
    43   if(R < L) return;
    44   if(L == R) {write(L), space; return;}
    45   write(f[L][R]), space;
    46   print(L, f[L][R] - 1);
    47   print(f[L][R] + 1, R);
    48 }
    49 
    50 int main()
    51 {
    52   n = read();
    53   for(int i = 1; i <= n; ++i) a[i] = read();
    54   for(int i = 1; i <= n; ++i) dp[i][i] = a[i], dp[i][i - 1] = 1;
    55   for(int L = 2; L <= n; ++L)
    56     for(int i = 1; i + L - 1 <= n; ++i)
    57       {
    58     int j = i + L - 1;
    59     for(int k = i; k <= j; ++k)
    60       {
    61         ll Max = dp[i][k - 1] * dp[k + 1][j] + a[k];
    62         if(Max > dp[i][j]) dp[i][j] = Max, f[i][j] = k;
    63       }
    64       }
    65   write(dp[1][n]); enter;
    66   print(1, n);
    67   return 0;
    68 }
    View Code
  • 相关阅读:
    Codeforces Gym 100571A A. Cursed Query 离线
    codeforces Gym 100500 J. Bye Bye Russia
    codeforces Gym 100500H H. ICPC Quest 水题
    codeforces Gym 100500H A. Potion of Immortality 简单DP
    Codeforces Gym 100500F Problem F. Door Lock 二分
    codeforces Gym 100500C D.Hall of Fame 排序
    spring data jpa 创建方法名进行简单查询
    Spring集成JPA提示Not an managed type
    hibernate配置文件中的catalog属性
    SonarLint插件的安装与使用
  • 原文地址:https://www.cnblogs.com/mrclr/p/9809207.html
Copyright © 2011-2022 走看看