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

    https://www.luogu.org/problemnew/show/P1040

    题解:这个题可以用动态规划或者记忆化搜索来做。因为如果要求加分最大的话,必须要求它的儿子结点加分最大,所以就有了最优子阶段。我们可以枚举根来更新最大值。中序遍历有个特点,在中序遍历这个序列上,某个点左边的序列一定是这个点的左子树,右边的序列,一定在这个点的右子树。root[i,j]表示[i,j]这段序列的根,递归输出先序遍历。注意初始化,f[i][i]=v[i],当序列只有I一个元素时,f[i][i]等于这个点本身的权值,当l==r-1时,此时是空树设为1。

    C++版本一

    #include <bits/stdc++.h>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<bitset>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<list>
    #include<map>
    #include<set>
    //#define DEBUG
    #define RI register int
    using namespace std;
    typedef long long ll;
    typedef __int128 lll;
    const int N=50;
    const int MOD=1e9+7;
    const double PI = acos(-1.0);
    const double EXP = 1E-8;
    const int INF = 0x3f3f3f3f;
    int t,n,m,k,q;
    int a[N];
    int dp[N][N];
    int root[N][N];
    int ser(int l,int r){
        if(dp[l][r]>0)return dp[l][r];
        if(l==r)return a[l];
        if(r<l)return 1;
        for(int i=l;i<=r;i++){
            int p=ser(l,i-1)*ser(i+1,r)+dp[i][i];
            if(p>dp[l][r]){
                dp[l][r]=p;root[l][r]=i;
            }
        }
        return dp[l][r];
    }
    void print(int l,int r){
        if(r<l)return;
        if(l==r){printf("%d ",l);return;}
        printf("%d ",root[l][r]);
        print(l,root[l][r]-1);
        print(root[l][r]+1,r);
    }
    int main()
    {
    #ifdef DEBUG
        freopen("input.in", "r", stdin);
        //freopen("output.out", "w", stdout);
    #endif
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            dp[i][i]=a[i];
            dp[i][i-1]=1;
        }
        printf("%d
    ",ser(1,n));
        print(1,n);
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

    C++版本二

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,v[39],f[47][47],i,j,k,root[49][49];
    void print(int l,int r){
        if(l>r)return;
        if(l==r){printf("%d ",l);return;}
        printf("%d ",root[l][r]);
        print(l,root[l][r]-1);
        print(root[l][r]+1,r);
    }
    int main() {
        scanf("%d",&n);
        for( i=1; i<=n; i++) scanf("%d",&v[i]);
        for(i=1; i<=n; i++) {f[i][i]=v[i];f[i][i-1]=1;}
        for(i=n; i>=1; i--)
            for(j=i+1; j<=n; j++)
                for(k=i; k<=j; k++) {
                    if(f[i][j]<(f[i][k-1]*f[k+1][j]+f[k][k])) {
                        f[i][j]=f[i][k-1]*f[k+1][j]+f[k][k];
                        root[i][j]=k;
                    }
                }
        printf("%d
    ",f[1][n]);
        print(1,n);
        return 0;
    }
    View Code
  • 相关阅读:
    Html.ActionLink 几种重载方式说明及例子
    2 python 文本特征提取 CountVectorizer, TfidfVectorizer
    模型调参---GridSearchCV
    1 NLP学习大纲
    pandas.dropna/isnull/fillna/astype的用法
    激活函数总结
    LeetCode--53 最大连续子序列(总结)
    LeetCode--44 通配符匹配
    LeetCode--Two_Sum
    css 背景图片自适应元素大小
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10282970.html
Copyright © 2011-2022 走看看