• P1040 加分二叉树


    题意:

    给定一个中序遍历为1,2,3,…,n的二叉树 每个结点有一个权值 定义二叉树的加分规则为: 左子树的加分× 右子树的加分+根的分数 若某个树缺少左子树或右子树,规定缺少的子树加分为1。 构造符合条件的二叉树 该树加分最大 输出其前序遍历序列

    想法:

    中序遍历的方法是 左子树 根 右子树

    因此二叉树左孩子遍历序列一定在根结点的左边,右孩子遍历序列一定在根结点的右边! 因此,假设二叉树的根结点为k,那么中序遍历为1,2,…,n的遍历序列,左孩子序列为1,2,…,k-1,右孩子序列为k+1,k+2,…,n

    f(i,j)中序遍历为i,i+1,…,j的二叉树的最大加分,则有: f(i,j)=max{f[i,k-1]*f[k+1,j] +d[k]} 显然 f(i,i)=d[i] 答案为f(1,n)

    枚举根节点就好了

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define ls nod<<1
    #define rs (nod<<1)+1
    
    const double eps = 1e-10;
    const int maxn = 100;
    const LL mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    LL f[maxn][maxn];
    int root[maxn][maxn];
    bool flag = true;
    
    inline LL find(int l,int r) {
       if (l > r)
           return 1;
       LL now;
       if (f[l][r] == -1) {
           for (int k = l;k <= r;k++) {
              now = find(l,k-1)*find(k+1,r) + f[k][k];
              if (now > f[l][r]) {
                  f[l][r] = now;
                  root[l][r] = k;
              }
           }
       }
       return f[l][r];
    }
    
    inline void pre(int l,int r) {
        if (l > r)
            return;
        if (flag) {
            flag = false;
        }
        else
            cout << " ";
        cout << root[l][r];
        pre(l,root[l][r]-1);
        pre(root[l][r]+1,r);
    }
    
    int main() {
        ios::sync_with_stdio(false);
        int n;
        cin >> n;
        for (int i = 1;i <= n;i++) {
            for (int j = 1;j <= n;j++)
                f[i][j] = -1;
        }
        for (int i = 1;i <= n;i++) {
            cin >> f[i][i];
            root[i][i] = i;
        }
        cout << find(1,n) << endl;
        flag = true;
        pre(1,n);
        return 0;
    }
  • 相关阅读:
    PDO应用
    分页查询
    PHP去除数组中重复数据的两个例子
    数据库访问(现用基本格式)
    克隆、加载类
    抽象类和接口
    静态
    PHP基础
    数据库的常用函数
    数据库的高级查询
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12345784.html
Copyright © 2020-2023  润新知