zoukankan      html  css  js  c++  java
  • hdu--1520--树形dp<写起来就是深搜啊>-<滚动数组优化>

    我肯定还没怎么理解树形dp啊...为什么写下去 就感觉是多了个状态转移方程的深搜呢?或者因为树形dp是依托在树这个数据结构上所进行的 所以是这样的?

    这题 被很多人 当做树形dp的入门题 的确....

    如果 u 是 v 的前驱即父母 那么

    dp[u][0] += max( dp[v][1] , dp[v][0] ) 0表示u不包括在内 1在内

    dp[u[[1] += dp[v][0]

    不太难写 还好这个

    主要是 每个树形dp都要找出根结点

    因为数据很宽松 我直接用了vector来写

     1 #include <iostream>
     2 #include <cstring>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int size = 6010;
     8 vector<int>ve[size];
     9 int val[size];
    10 int dp[size][2];
    11 int in[size];
    12 
    13 void dfs( int u )
    14 {
    15     int Size , v;
    16     Size = ve[u].size();
    17     dp[u][1] = val[u];
    18     for( int i = 0 ; i<Size ; i++ )
    19     {
    20         v = ve[u][i];
    21         dfs(v);
    22         dp[u][0] += max( dp[v][0] , dp[v][1] );
    23         dp[u][1] += dp[v][0];
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     cin.sync_with_stdio(false);
    30     int n , x , y , z;
    31     while( cin >> n )
    32     {
    33         memset( dp , 0 , sizeof(dp) );
    34         memset( in , 0 , sizeof(in) );
    35         for( int i = 1 ; i<=n ; i++ )
    36         {
    37             cin >> val[i];
    38             ve[i].clear();
    39         }
    40         while(1)
    41         {
    42             cin >> x >> y;
    43             ve[y].push_back(x);
    44             in[x] ++;
    45             if( !x && !y )
    46                 break;
    47         }
    48         for( int i =1 ; i<=n ; i++ )
    49         {
    50             if( !in[i] )
    51             {
    52                 z = i;
    53                 break;
    54             }
    55         }    
    56         dfs(z);
    57         cout << max( dp[z][0] , dp[z][1] ) << endl;
    58     }
    59     return 0;
    60 }
    View Code

    看了discuss里面一个人的滚动数组写法 很有感触

    因为这边每个结点只需要利用与它直接相连的后驱结点的信息 所以我们可以用滚动数组优化

    要注意的是arr数组 必须写在函数内 使它变成局部变量

     1 #include <iostream>
     2 #include <cstring>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int size = 6010;
     8 vector<int>ve[size];
     9 int val[size];
    10 int dp[2] = {0,0};
    11 int in[size];
    12 
    13 void dfs( int u )
    14 {
    15     int arr[2] = {0,0};
    16     int Size = ve[u].size();
    17     for( int i = 0 ; i<Size ; i++ )
    18     {
    19         dfs( ve[u][i] );
    20         arr[0] += max( dp[0] , dp[1] );
    21         arr[1] += dp[0];
    22     }
    23     dp[0] = arr[0];
    24     dp[1] = arr[1] + val[u];
    25 }
    26 
    27 int main()
    28 {
    29     cin.sync_with_stdio(false);
    30     int n , x , y , z , sum;
    31     while( cin >> n )
    32     {
    33         sum = 0;
    34         memset( in , 0 , sizeof(in) );
    35         for( int i = 1 ; i<=n ; i++ )
    36         {
    37             cin >> val[i];
    38             ve[i].clear();
    39         }
    40         while(1)
    41         {
    42             cin >> x >> y;
    43             ve[y].push_back(x);
    44             in[x] ++;
    45             if( !x && !y )
    46                 break;
    47         }
    48         for( int i =1 ; i<=n ; i++ )
    49         {
    50             if( !in[i] )
    51             {
    52                 z = i;
    53                 break;
    54             }
    55         }    
    56         dfs(z);
    57         cout << max(dp[0],dp[1]) << endl;
    58     }
    59     return 0;
    60 }
    View Code

    他还写了种 多叉树 转2叉树后的写法 我感觉其实这个区别不算大吧..

    但其实核心都是 开头提到的 状态转移方程

    today:

      听到一些事

      明明和你不相关

      但是能在心理拐几个弯的想到你

      

    just follow your heart
  • 相关阅读:
    According to TLD or attribute directive in tag file, attribute end does not accept any expressions
    Several ports (8080, 8009) required by Tomcat v6.0 Server at localhost are already in use.
    sql注入漏洞
    Servlet—简单的管理系统
    ServletContext与网站计数器
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    java 使用相对路径读取文件
    shell编程 if 注意事项
    Ubuntu12.04下eclipse提示框黑色背景色的修改方法
    解决Ubuntu环境变量错误导致无法正常登录
  • 原文地址:https://www.cnblogs.com/radical/p/3965927.html
Copyright © 2011-2022 走看看