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 }
  • 相关阅读:
    Mac快捷键符号解释及用法介绍
    Mac使用小技巧:Fn键的妙用技巧
    Mac快捷键大全
    idea 开发SpringBoot项目并打包docker镜像部署到节点上
    .netcore linux开机自启脚本
    javascript Event Loop
    mysql函数使用技巧
    MySql查找慢查询sql
    js优先队列和链表
    mysql性能优化
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13081256.html
Copyright © 2011-2022 走看看