• hdu1011 Starship Troopers 树形DP


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011

    思路:很明显的树形背包

    定义dp[root][m]表示以root为根,派m个士兵的最优解,那么dp[root][m]=max(dp[root][m],dp[root][k]+dp[son][j]) k+j<=m son为root 的孩子

    树形dp的思路一般就是着父亲和孩子节点之间的转移关系,然后从dfs到叶子节点,然后开始从叶子节点向上进行DP

    最重要的就是建树和dfs求解的过程,如果掌握了怎样建树和怎样进行DP,那么树形DP就会发现很简单了。。。。

    加油!!!ACMer

    代码如下:

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace std;
     6 #define MAX 110
     7 int n,m;
     8 int dp[MAX][MAX];
     9 int tol;
    10 class node
    11 {
    12    public:
    13    int to;
    14    int next;
    15 };
    16 node edge[MAX*3];
    17 int head[MAX];
    18 int bugs[MAX];
    19 int brain[MAX];
    20 int vis[MAX];
    21 void Build_Tree(int u,int v)
    22 {
    23         edge[tol].to=v;
    24         edge[tol].next=head[u];
    25         head[u]=tol++;
    26 }
    27 void init()
    28 {
    29         memset(head,-1,sizeof(head));
    30         memset(dp,0,sizeof(dp));
    31         memset(vis,0,sizeof(vis));
    32         memset(bugs,0,sizeof(bugs));
    33         memset(brain,0,sizeof(brain));
    34         tol=0;
    35 }
    36 void dfs(int root)
    37 {
    38    vis[root]=1;
    39    int cost=(bugs[root]+19)/20;//important
    40    for(int i=cost;i<=m;i++)
    41            dp[root][i]=brain[root];
    42    for(int i=head[root];i!=-1;i=edge[i].next)
    43    {
    44            if(vis[edge[i].to]) continue;
    45            int son=edge[i].to;
    46            dfs(son); 
    47 
    48            for(int j=m;j>=cost;j--)
    49            {
    50                    for(int k=1;k+j<=m;k++)
    51                        if(dp[son][k])
    52                                dp[root][j+k]=max(dp[root][j+k],dp[son][k]+dp[root][j]);
    53            }
    54    }
    55 }
    56 int main()
    57 {
    58         while(scanf("%d%d",&n,&m)!=EOF)
    59         {
    60              if(n==-1||m==-1) break;
    61              init();
    62              for(int  i=1;i<=n;i++)
    63                   scanf("%d%d",&bugs[i],&brain[i]);
    64              for(int i=1;i<n;i++)
    65              {
    66                      int u,v;
    67                      scanf("%d%d",&u,&v);
    68                      Build_Tree(u,v);
    69                      Build_Tree(v,u);
    70              }
    71             if(m==0) {cout<<"0"<<endl;continue;}
    72             dfs(1);
    73             cout<<dp[1][m]<<endl;
    74 
    75         }
    76         return 0;
    77 }
    View Code
  • 相关阅读:
    struts2中拦截器与过滤器之间的区别
    使用struts2中默认的拦截器以及自定义拦截器
    图解Tomcat类加载机制
    Eclipse项目中引用第三方jar包时将项目打包成jar文件的两种方式
    SQL中的四种连接方式
    My97datepicker日期控件
    Java中如何判断一个日期字符串是否是指定的格式
    jxl导入/导出excel
    优化myeclipse启动速度以及解决内存不足问题
    170726、常用 Git 命令清单
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu1011.html
Copyright © 2020-2023  润新知