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

    https://www.luogu.com.cn/problem/P1040

    n很小,可以树形dp或者区间dp。

    设fij为从i到j的最大加分值,则有f[i][j]=max(f[i][k-1]*f[k+1][j]+f[k][k])。

    有一个小技巧,将f[i][i-1]全部设置为1,这样的话搜索到叶子就也可以按照通式dp了。

    对于输出前序遍历(根,左树,右树)我们再树形dp一下就行了。

    树形dp比较清晰明了(但是耗内存)。不想写树形dp的话递推式如上。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 inline int read()
     7 {
     8     int x=0,w=1;char c=getchar();
     9     while(!isdigit(c)){
    10         if(c=='-')w=-1;
    11         c=getchar();
    12     }
    13     while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    14     return x*w;
    15 }
    16 const int maxn=35;
    17 int n;
    18 int f[maxn][maxn],a[maxn],ro[maxn][maxn];
    19 int search(int l,int r)
    20 {
    21     if(l>r)return 1;
    22     if(l==r){ro[l][r]=l;return f[l][r];}
    23     if(f[l][r])return f[l][r];
    24     for(int w,i=l;i<=r;i++)
    25     {
    26         w=search(l,i-1)*search(i+1,r)+f[i][i];
    27         if(w>f[l][r])f[l][r]=w,ro[l][r]=i;
    28     }
    29     return f[l][r];
    30 }
    31 void print(int l,int r)
    32 {
    33     if(l>r)return ;
    34     printf("%d ",ro[l][r]);
    35     print(l,ro[l][r]-1);
    36     print(ro[l][r]+1,r);
    37 }
    38 int main()
    39 {
    40     n=read();
    41     for(int i=1;i<=n;i++)f[i][i]=read();
    42     search(1,n);
    43     printf("%d\n",f[1][n]);
    44     print(1,n);//发扬先辈遗德,恢弘志士之气 
    45     return 0;
    46 }
  • 相关阅读:
    javascript闭包函数
    取消后续内容执行
    vs安装失败,发生严重错误,错误号:Error 0x80070643
    ref
    深入类的方法
    学习过程中的三个小小程序
    SQL Server 中存储过程的练习
    SQL Server系统存储过程
    SQL-server的事务,视图和索引
    用C#,SQL Server编写的音乐播放软件
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13081256.html
Copyright © 2011-2022 走看看