• luogu P2015 二叉苹果树


    一道qq姐和dtx很早就做了的题www

    想学树形dp就是从这道题开始的

    然后做了几道题

    之后被难住了

    于是回来做这道题

    首先这道题保证了是一棵二叉树

    emmmmm

    然后一个dp数组

    dp[u][j] 代表保留u节点j条边的最大值

    题目保证1为根,那么结果就是dp[1][Q]

    状态转移方程:

    dp[u][j] = max(dp[u][j],dp[u][j - k - 1] + dp[v][k] + edge[i].weight)

    v为u的子节点,k是枚举v保留的边的数

    保留j条边的话,其中有一条边是u和v所连的边

    所以保留v节点k条边再加上u节点剩下的可以保留的j - 1 - k条边再加上u和v之间的边

    状态转移方程真的太难想了www

    看看代码吧

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define maxn 110
    
    struct EDGE{
      int nxt,to,weight;
    }edge[maxn * 2];//因为忘了开二倍所以emmm
    
    int head[maxn],cnt;
    int dp[maxn][maxn];
    int n,q;
    
    void add(int x,int y,int w){
      edge[++cnt].nxt = head[x];
      edge[cnt].to = y;
      head[x] = cnt;
      edge[cnt].weight = w;
    }
    
    int treedp(int u,int fa){
      int num = 0;
      for(int i = head[u];i;i = edge[i].nxt){
        int v = edge[i].to;
        if(v != fa){//存的双向所以防止死循环
          num += treedp(v,u) + 1;//return一个值,子树的边数,再加上相连的一条
          for(int j = min(num,q);j > 0;j--)
        for(int k = min(num,j);k >= 0;k--)
          dp[u][j] = max(dp[u][j],dp[u][j - k - 1] + dp[v][k] + edge[i].weight);
        }
      }
      return num;
    }
    
    int main(){
      scanf("%d%d",&n,&q);
      for(int i = 1;i < n;i++){
        int x,y,w;
        scanf("%d%d%d",&x,&y,&w);
        add(x,y,w);
        add(y,x,w);
      }
      treedp(1,0);
      printf("%d",dp[1][q]);
      return 0;
    }

    【令人头大

    /*

    然后最后插一句没什么意义的感慨

    我们都是

          渺小而平庸的

                无名之辈

    谢谢你们能在这么短暂的生命之中,记住我的名字

     (没错就是看完电影哭的不行之后的伤春悲秋www

    */ 

  • 相关阅读:
    面试题目以及注意事项
    jQuery Ajax 实例 ($.ajax、$.post、$.get)
    前端知识大全
    jquery实现2级联动
    [转]那些年我们一起清除过的浮动
    使用kubeadm在CentOS上搭建Kubernetes1.14.3集群
    企业优秀运维人员20道必会iptables面试题
    通过nginx日志利用shell统计日pv和uv
    php访问mysql接口pdo-mysql安装
    何查看已经安装的nginx、apache、mysql和php的编译参数
  • 原文地址:https://www.cnblogs.com/sevenyuanluo/p/10260677.html
Copyright © 2020-2023  润新知