• 加分二叉树


    https://loj.ac/problem/10158

    题目描述

      设一个点的中序遍历为(1,2,3,...,n),二叉树的分数为左子树分数( imes)右子树分数+根的分数。求最大分数及对应的前序遍历。

    思路

      我们考虑用(f[i][j])表示(isim j)的这一段的最大分数,我们只要暴力枚举以(kin [i,j])为根的点的最大分数,并记录一下这一段以那个点为根即可。最后递归求一下前序遍历即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    int read()
    {
    	int res=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
    	return res*w;
    }
    void write(int x)
    {
    	if(x<0){putchar('-');x=-x;}
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    }
    void writeln(int x)
    {
    	write(x);
    	putchar('
    ');
    }
    
    int f[40][40],a[40],p[40][40];
    void output(int l,int r)
    {
    	int k=p[l][r];
    	write(k);putchar(' ');
    	if(k-1>=l)output(l,k-1);
    	if(k+1<=r)output(k+1,r);
    }
    int main()
    {
    	int n=read();
    	for(int i=1;i<=n;i++)
    		a[i]=read();
    	for(int i=1;i<=n+1;i++)
    		f[i][i-1]=1;
    	for(int i=1;i<=n;i++)
    		f[i][i]=a[i],p[i][i]=i;
    	for(int len=2;len<=n;len++)
    		for(int l=1;l<=n-len+1;l++)
    		{
    			int r=l+len-1;
    			for(int k=l;k<=r;k++)
    				if(f[l][r]<f[l][k-1]*f[k+1][r]+a[k])
    				{
    					f[l][r]=f[l][k-1]*f[k+1][r]+a[k];
    					p[l][r]=k;
    				}
    		}
    	writeln(f[1][n]);
    	output(1,n);
    }
    
  • 相关阅读:
    Render Props
    react16新特性
    typescript
    calc
    类数组
    promise fullfill状态时 value是一个promise,那么此promise.then()里面收到的是什么
    M个同样的苹果放N个同样的盘子,允许有盘子空着, 问有多少种放法?
    history
    js创建二维数组
    钉钉-E应用开发初体验(企业内部应用)
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11838511.html
Copyright © 2020-2023  润新知