• VJP1100 加分二叉树(树形DP)


    链接

    归属树形DP  做着更像记忆化

    DP很好做 就是那个输出路径恶心了。。改代码 从60多行改到120多行。。dp从1维加到三维。。

    先类似记忆化搜索整棵树 枚举以i为根节点的最大值 子树类似

    求完最大值 再递归搜一下前序 这题不记忆化会超时

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 using namespace std;
      7 #define LL long long
      8 LL dp[35][35][35],a[35];
      9 int n,path[35],to;
     10 LL dfs(int root,int l,int r)
     11 {
     12     if(dp[root][l][r])
     13     return dp[root][l][r];
     14     if(l==r)
     15         return dp[root][l][r] = a[l];
     16     int i,j;
     17     LL tt =0;
     18     if(l==root)
     19     {
     20         for(i = root+1 ; i <= r ; i++)
     21             tt = max(tt,dfs(i,root+1,r)+a[root]);
     22     }
     23     else if(r==root)
     24     {
     25         for(i = l ; i < root ; i++)
     26             tt = max(tt,dfs(i,l,root-1)+a[root]);
     27     }
     28     else
     29     {
     30         for(i = l; i < root ; i++)
     31             for(j = root+1 ; j <= r; j++)
     32             {
     33                 LL s1 = dfs(i,l,root-1);
     34                 LL s2 = dfs(j,root+1,r);
     35                 tt = max(tt,s1*s2+a[root]);
     36             }
     37     }
     38     return dp[root][l][r]=tt;
     39 }
     40 void find(int u,int l,int r,int v)
     41 {
     42     int i,j,x1,x2;
     43     if(l==r)
     44         return ;
     45     int f = 0;
     46     if(u==l)
     47     {
     48         for(i = u+1 ; i <= r ; i++)
     49         if(dp[i][u+1][r]+a[u]==dp[u][l][r])
     50         {
     51             x1 = i;
     52             break;
     53         }
     54         path[v+1] = x1;
     55         find(x1,u+1,r,v+1);
     56     }
     57     else if(u==r)
     58     {
     59         for(i = l ; i < u ; i++)
     60         if(dp[i][l][u-1]+a[u]==dp[u][l][r])
     61         {
     62             x1 = i;
     63             break;
     64         }
     65         path[v+1] = x1;
     66         find(x1,l,u-1,v+1);
     67     }
     68     else
     69     {
     70         for(i = l; i < u ; i++)
     71         {
     72             for(j = u+1; j <= r ;j++)
     73             if(dp[i][l][u-1]*dp[j][u+1][r]+a[u]==dp[u][l][r])
     74             {
     75                 x1 = i;
     76                 x2 = j;
     77                 f = 1;
     78                 break;
     79             }
     80             if(f) break;
     81         }
     82         path[v+1] = x1;
     83         path[v+1+u-l] = x2;
     84         find(x1,l,u-1,v+1);
     85         find(x2,u+1,r,v+1+u-l);
     86     }
     87 }
     88 int main()
     89 {
     90     int i;
     91     cin>>n;
     92     for(i = 1; i <= n ; i++)
     93     cin>>a[i];
     94     LL ans = 0;
     95     for(i = 1; i <= n ; i++)
     96     {
     97         LL s = dfs(i,1,n);
     98         if(s>ans)
     99         {
    100             ans =s;
    101             path[1] = i;
    102         }
    103     }
    104     cout<<ans<<endl;
    105     find(path[1],1,n,1);
    106     for(i = 1; i < n ; i++)
    107     cout<<path[i]<<" ";
    108     cout<<path[n]<<endl;
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    2018年强化学习领域十篇重要论文(附源码)[转]
    【转载】 再励学习面试真题 (强化学习面试真题)
    枸杞常泡水喝好吗?
    亲历亚马逊、华为机器学习面试,原来考官想听到这些回答[转]
    阿里面试 深度学习[转]
    强化学习(四)用蒙特卡罗法(MC)求解
    初识kaggle,以及记录 kaggle的使用
    强化学习(三)用动态规划(DP)求解
    CORTEX-M3中断的现场保护问题
    地球是圆的怎么还分东西方
  • 原文地址:https://www.cnblogs.com/shangyu/p/3280187.html
Copyright © 2020-2023  润新知