• ural 1018 Binary Apple Tree(树dp)


    http://acm.timus.ru/problem.aspx?space=1&num=1018

    题意:

    有一棵苹果树,苹果树的是一棵二叉树,共N个节点,树节点编号为1~N,编号为1的节点为树根,边可理解为树的分枝,每个分支都长着若干个苹果,现在要要求减去若干个分支,保留M个分支,要求这M个分支的苹果数量最多。

    树dp跟一般的dp的解决方案一样也是三个步骤:1、确定状态;2、状态转移;3、算法实现。(算法的实现要满足无后效性等基本原则)

    由于树的结构,使用记忆化搜索比较容易实现。

    题目分析:设dp[u][q]为由第u个节点往下取q个分支的最优值,则当前节点的dp值来源于其子节点,这里就要有子节点的个数进行分类讨论。
    当子节点数为1时,就只能沿该路径走下去,dp[u][q] = dp[child][q-1] + maz[u][child];
    当子节点数为2时,dp[u][q] = max{dp[child1][k]+maz[u][child1] + dp[child2][q-k-2] + maz[u][child2]}或者像节点数为1的情况一样只来源于其中一个子节点。
    View Code
     1 /*
     2 Author:Zhaofa Fang
     3 Lang:C++
     4 */
     5 #include <cstdio>
     6 #include <cstdlib>
     7 #include <sstream>
     8 #include <iostream>
     9 #include <cmath>
    10 #include <cstring>
    11 #include <algorithm>
    12 #include <string>
    13 #include <utility>
    14 #include <vector>
    15 #include <queue>
    16 #include <stack>
    17 #include <map>
    18 #include <set>
    19 using namespace std;
    20 
    21 typedef long long ll;
    22 #define DEBUG(x) cout<< #x << ':' << x << endl
    23 #define REP(i,n) for(int i=0;i < (n);i++)
    24 #define REPD(i,n) for(int i=(n-1);i >= 0;i--)
    25 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
    26 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
    27 #define PII pair<int,int>
    28 #define PB push_back
    29 #define MP make_pair
    30 #define ft first
    31 #define sd second
    32 #define lowbit(x) (x&(-x))
    33 #define INF (1<<30)
    34 
    35 int dp[110][110],maz[110][110];
    36 vector<int>vec[110];
    37 
    38 int dfs(int u,int q,int f){
    39     if(vec[u].size()==0 || (vec[u].size()==1&&f!=-1) || q<=0){
    40         return 0;
    41     }
    42     if(!dp[u][q]){
    43         int tmp = 0;
    44         if((vec[u].size()==2 && f!=-1) || (vec[u].size()==1 && f==-1)){
    45             int v = vec[u][0];
    46             if(v == f)v = vec[u][1];
    47             tmp = dfs(v,q-1,u) + maz[u][v];
    48         }
    49         else {
    50             int v[3]={0};int nn = 0;
    51             REP(i,vec[u].size()){
    52                 if(vec[u][i] != f)v[nn++] = vec[u][i];
    53             }
    54             FOR(i,0,q-2){
    55             int cnt = dfs(v[0],i,u) + maz[u][v[0]];
    56             cnt += dfs(v[1],q-i-2,u) + maz[u][v[1]];
    57             tmp = max(tmp,cnt);
    58             }
    59             tmp = max(tmp,dfs(v[0],q-1,u) + maz[u][v[0]]);
    60             tmp = max(tmp,dfs(v[1],q-1,u) + maz[u][v[1]]);
    61         }
    62         dp[u][q] = tmp;
    63     }
    64     return dp[u][q];
    65 }
    66 
    67 int main(){
    68     //freopen("in","r",stdin);
    69     //freopen("out","w",stdout);
    70     int n,q;
    71     while(~scanf("%d%d",&n,&q)){
    72         memset(dp,0,sizeof(dp));
    73         memset(maz,0,sizeof(maz));
    74         FOR(i,1,n)vec[i].clear();
    75         REP(i,n-1){
    76             int a,b,x;
    77             scanf("%d%d%d",&a,&b,&x);
    78             maz[a][b] = maz[b][a] = x;
    79             vec[a].PB(b);vec[b].PB(a);
    80         }
    81         int ans = dfs(1,q,-1);
    82         printf("%d\n",ans);
    83     }
    84     return 0;
    85 }
    by Farmer
  • 相关阅读:
    web服务器,应用程序服务器,http服务器的区别
    tomcat、weblogic、jboss的区别,容器的作用
    linux系统编辑神器 -vim用法大全
    web弹出对话框
    c#获取打印机列表
    cookie
    lodop打印多页
    lodop判断是否打印成功
    一般处理程序
    让图片在div中居中
  • 原文地址:https://www.cnblogs.com/fzf123/p/2956328.html
Copyright © 2020-2023  润新知