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

    本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1040


    虽然他在洛谷上是分类只是深度优先搜索,但比较好的做法是记忆化搜索树形DP。

    树根是不确定的,因此需要枚举。我们可以定义状态dp[l][r]表示中序遍历区间为[l,r]所能得到的最大分数,利用记忆化搜索,很容易求出[1,n]的dp值;而这道题相对难实现的是给出分数最大方案的前序遍历,我们可以再开一个数组dp_root[l][r]表示[l,r]取到最大分数时选取的树根,然后跑一遍前序遍历即可。

     1 #include<cstdio>
     2 const int maxn=35;
     3 int n,dp[maxn][maxn],dp_root[maxn][maxn];
     4 int dfs(int l,int r) {
     5     if(l>r) return 1;
     6     if(!dp[l][r])
     7         for(int i=l;i<=r;++i) {
     8             int now=dp[i][i]+dfs(l,i-1)*dfs(i+1,r);
     9             if(now>dp[l][r]) dp[l][r]=now,dp_root[l][r]=i;
    10         }
    11     return dp[l][r];
    12 }
    13 void print(int l,int r) {
    14     if(!(l==1&&r==n)) putchar(' ');
    15     int rt=dp_root[l][r];
    16     printf("%d",rt);
    17     if(l<=rt-1) print(l,rt-1);
    18     if(rt+1<=r) print(rt+1,r);
    19 }
    20 int main() {
    21     scanf("%d",&n);
    22     for(int i=1;i<=n;++i) {scanf("%d",&dp[i][i]);dp_root[i][i]=i;}
    23     int ans=dfs(1,n);
    24     printf("%d
    ",ans);
    25     print(1,n);
    26     return 0;
    27 }
    AC代码
  • 相关阅读:
    对象的存在是因为别人要用它
    图书馆借书程序我的分析
    版权迷思
    第四章 算法
    不可持续的天才教育
    第一章 你要做什么?
    win8 开发新格局分析
    水果机的几率设计
    我的理想
    windows 8,微软创新之路
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9686898.html
Copyright © 2011-2022 走看看