luogu 2014 选课 树上背包

树上背包

#include<bits/stdc++.h>

using namespace std;

const int N=310;
const int inf=0x3f3f3f3f;
vector<int> son[N];
int f[N][N],s[N],n,m;

void dfs(int u){
    f[u][0]=0;
    for(int i=0;i<son[u].size();i++){
        int v=son[u][i];
        dfs(v);
        for(int j=m;j>0;j--)
        for(int k=j;k>=0;k--)
        if(j-k>=0)
        f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]);
    }
    if(u!=0){
        for(int i=m;i>0;i--)
        f[u][i]=f[u][i-1]+s[u];
    }
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x>>s[i];
        son[x].push_back(i);
    }
    memset(f,-inf,sizeof f);
    dfs(0);
    printf("%d\n",f[0][m]);
}

原文地址:https://www.cnblogs.com/asdic/p/9697183.html

时间: 2024-10-08 03:06:23

luogu 2014 选课 树上背包的相关文章

P2014 选课 (树上背包)

树上背包: 树形背包就是原始的树上动归+背包,一般用来处理以一棵树中选多少点为扩展的一类题,基本做法与树上dp无异,不过在状态转移方程中会用到背包的思想. 它基本上是这个样子的: 存图),然后dfs进去补全子节点的信息,f数组的意思是以fa为中转点,找出fa往下的可取1~j个点时各自的最大收益. void dfs(int fa){ for(int i=0;i<son[fa].size();i++){ int ny=son[fa][i]; dfs(ny); for(int j=m+1;j>=1;

MZOJ 1132 &amp;&amp; LuoGu P2014 选课

MZOJ 1132 && LuoGu P2014 选课    [传送门] #include<bits/stdc++.h> #define maxn 100000 #define maxm 500 using namespace std; int k=0,head[maxn]; int f[maxm][maxm],w[maxn]; int ans=0; int N,M; struct node{ int v,nxt; }e[maxn<<1]; void adde(in

【BZOJ】4033: [HAOI2015]树上染色 树上背包

[题目]#2124. 「HAOI2015」树上染色 [题意]给定n个点的带边权树,要求将k个点染成黑色,使得 [ 黑点的两两距离和+白点的两两距离和 ] 最大.n<=2000. [算法]树上背包 [题解]设f[i][j]表示子树i中有j个黑点对答案的贡献(包括点 i 到父亲的边 p ),由于边p的贡献只和 j 有关,所以最后再统计. 所以做树上背包即可,注意这题特殊在f[x][0]≠0,所以初始f[x][k]+=f[y][0],然后不要把0作为物品. 最后统计边p的贡献:w[p] *(子树内黑点

HihoCoder 1055 刷油漆 (树上背包)

题目:https://vjudge.net/contest/323605#problem/A 题意:一棵树,让你选择m个点的一个连通块,使得得到的权值最大 思路:树上背包,我们用一个dp数组,dp[i][j] ,代表以i为根时的选其子树j个节点所得到的最大值,然后我们对于每个以i为根我们当做有m件物品,然后对于不同的子树当作不同的分组即可 #include<bits/stdc++.h> #define maxn 105 #define mod 1000000007 using namespac

LuoGu P2014选课(人生第一个树上背包)

(著名哲学家沃兹基硕德曾经说过:“$QuickSilverX$ $is$ $a$ $BB$”) 就是课与课可能有一些优先关系 这种关系我们可以通过图论建模来解决 不难发现,若将优先选修课向当前课连边,就会生成森林(每门课只有一个选修课,也就只有一条入边) 将所有无入边(没有优先课)的结点与0相连,形成树 ~~不难~~发现这是一个树上DP与背包... 树本身就是个递归的结构,我们每个结点的状态肯定是先递归处理儿子结点的状况来转移的 定义状态 $F[i][j][k]$ 表示第 $i$ 的前 $j$

Luogu P2014 选课 题解报告

题目传送门 [题目大意] 有n门选修课,每一门课都有固定的学分$S_i$,每个学生可以选m门课.有些选修课有先修课,每一门课最多只有一门先修课,求能获得的最多学分. [思路解析] 设f[x][t]表示在以x结点为根的子树中选t门课能获得的最大学分,x的子结点集合为son[x],子结点个数为p,且对于x的第i个子结点son[i],以其为根结点的子树中选课数量为$C_i$,则转移方程为:$$f[x][t]=max(\sum_{i=1}^{p}f[son[i]][c[i]])+s[i](满足\sum_

Luogu P2014 选课

题面 对于这道题,我们考虑在树形dp上套背包.我们会非常自然的采用dfs扫描整棵树,然后对树上的每个节点都进行一次背包. 计\(dp[i][j]\)为在以第\(i\)号节点为根结点的子树中,用题目中选法选取\(j\)项的最大值. 我们在dfs的过程中,采用递归的方式,在子节点都处理完之后,便考虑将所有子节点的答案综合,得到当前节点的答案. 很显然,就是在容量为\(j\)的01背包中放下\(i\)节点的所有子节点背包中的答案,我们很容易想到下面的DP方程 \[f[x][j]=max(f[to][k

hdu2415(树上背包)

这道题好像没什么人写题解,于是写了一发 题意:有个坏蛋想要参加竞选,需要得到m个人的支持,买通第i个人(1<=i<=n)需要一个cost[i],同时这些人又有上下属关系,只要买通了领导,他的下属(可以是下属的下属)也会给你投票,问最少要花多少钱 数据范围:N<=200,m<=n; 其实就是比较裸的树上分组背包,每个子节点的背包是一个组,选自己也是一个组,dfs搞一搞就好了,然而字符串处理实在恶心..... #include<string> #include<cst

【题解】Luogu P2014 选课

Problem 树上背包问题的典例,记下来 solution 设\(dp[x][t]\)表示以\(x\)为子树,选\(t\)门课获得的最大学分 设\(p\)是\(x\)的子节点数量,\(c_i\)是\(x\)的子节点\(y_i\)选修的课数 转移方程如下 \[dp[x][t]=max_{\sum_{i=1}^pc_i=t-1}\{\sum_{i=1}^pdp[y_i][c_i]\}+pnt[x]\] 事实上,这是一个分组背包模型,对于每个节点\(x\),每个子节点\(y_i\)是一个组,在其中选