zoukankan      html  css  js  c++  java
  • 洛谷 P2014 [CTSC1997]选课(树形DP)

    题目链接:https://www.luogu.com.cn/problem/P2014

    一道树上关于点的0-1背包问题。

    这道题背包容量实际为m,但是可以让背包容量为m+1,因为0这个似虚非虚的根是一定要选的,并且它的贡献为0。

    那么方程式:$dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k])$

    其中,dp[u][j]表示以u为根,子树节点数为j的最大值。初始化的话:sum[u]=1,dp[u][1]=val[u],这是显然的。

    不得不说树形DP的边界都好奇特。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int N=400;
     6 struct node{
     7     int to,next;
     8 }edge[N];
     9 int head[N],tot;
    10 int dp[N][N],sum[N],n,m;
    11 void add(int u,int v){
    12     edge[tot].to=v;
    13     edge[tot].next=head[u];
    14     head[u]=tot++;
    15 }
    16 void DFS(int u,int fa){
    17     sum[u]=1;
    18     for(int i=head[u];i!=-1;i=edge[i].next){
    19         int v=edge[i].to;
    20         if(v==fa) continue;
    21         DFS(v,u);
    22         sum[u]+=sum[v];
    23         for(int j=min(m+1,sum[u]);j>=1;j--){
    24             for(int k=min(j-1,sum[v]);k>=0;k--){
    25                 dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
    26             }
    27         }
    28     }
    29 }
    30 int main(){
    31     memset(head,-1,sizeof(head));
    32     scanf("%d%d",&n,&m);
    33     for(int i=1;i<=n;i++){
    34         int s,k;
    35         scanf("%d%d",&k,&s);
    36         add(k,i); dp[i][1]=s;
    37     }
    38     DFS(0,-1);
    39     printf("%d
    ",dp[0][m+1]);
    40     return 0;
    41 }
    AC代码
  • 相关阅读:
    Learning KVM
    KVM HOST IN A FEW LINES OF CODE
    VM学习—实现自己的内核
    gvisor bluepillHandler + SwitchToUser
    GO语言调试利器dlv快速上手
    gvisor debug
    gvisor 系统 调用初始化
    Android开发 02
    Android开发 01
    加分项
  • 原文地址:https://www.cnblogs.com/New-ljx/p/12594164.html
Copyright © 2011-2022 走看看