题目描述 Description
学校实行学分制。每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分。学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的。学生选修了这M门课并考核通过就能获得相应的学分。

在选修课程中,有些课程可以直接选修,有些课程需要一定的基础知识,必须在选了其它的一些课程的基础上才能选修。例如《Frontpage》必须在选修了《Windows操作基础》之后才能选修。我们称《Windows操作基础》是《Frontpage》的先修课。每门课的直接先修课最多只有一门。两门课也可能存在相同的先修课。每门课都有一个课号,依次为1,2,3,…。 例如:

表中1是2的先修课,2是3、4的先修课。如果要选3,那么1和2都一定已被选修过。   
你的任务是为自己确定一个选课方案,使得你能得到的学分最多,并且必须满足先修课优先的原则。假定课程之间不存在时间上的冲突。

输入描述 Input Description
输入文件的第一行包括两个整数N、M(中间用一个空格隔开)其中1≤N≤300,1≤M≤N。
以下N行每行代表一门课。课号依次为1,2,…,N。每行有两个数(用一个空格隔开),第一个数为这门课先修课的课号(若不存在先修课则该项为0),第二个数为这门课的学分。学分是不超过10的正整数。

输出描述 Output Description
输出文件只有一个数,实际所选课程的学分总数。

样例输入 Sample Input
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2

样例输出 Sample Output
13

分析:
描述:
有些课程可以直接选修,有些课程必须在选了其他的一些课程后(最多一个)才能选修

这个‘最多一个’的限制很奇怪
一对一的关系实际上就是爸爸和儿子的关系
所以整个课表可以抽象成一片森林
为了方便,我们可以建立一个虚拟节点root
把森林变成一棵树
f[i][j]表示以i为根的子树选了j个节点的最大值
树上背包
(什么?背包从来没在树上做过啊,先拿来前辈的代码%%)

f[i][j]对于每一个i有两种情况:
1.i不修,则i的孩子一定不修,所以为0;
2.i修,则i的孩子们可修可不修
(在这里其实可以将其转化为将j-1个对i的孩子们进行资源分配的问题,也属于背包问题)

tip

分析中说要建立一个虚拟根root,
实际上并不用特意的构建,
所有没有先修课的课程,在描述的时候第一个数都是0
这样我们直接把0当做root,连边即可

m++; //以0为根,0也选上了,所以总的选课数要++

g是一个很神奇的数组

在一开始的时候用g数组复制一下当前的f信息,在之后的转移时,直接用g
具体原因实在不清楚

循环顺序很重要,
在第二层循环的时候,l要从大到小
在维护i必修的循环时,l从大到小
保证每一个状态只加了一个v[now]

这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>using namespace std;const int N=310;
struct node{int x,y,nxt;
};
node way[N<<1];
int st[N],tot=0,f[N][N],v[N],size[N];
int n,m,g[N];void add(int u,int w)
{tot++;way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;tot++;way[tot].x=w;way[tot].y=u;way[tot].nxt=st[w];st[w]=tot;
}void dfs(int now,int fa)
{size[now]=1;  //计算子树大小 for (int i=st[now];i;i=way[i].nxt)if (way[i].y!=fa)dfs(way[i].y,now),size[now]+=size[way[i].y];
}void doit(int now,int fa,int k)  //从叶子结点开始dp,直接找叶子好烦,干脆递归
{int i,j,l;for (i=st[now];i;i=way[i].nxt){if (way[i].y!=fa){doit(way[i].y,now,k);for (j=0;j<size[now];j++) g[j]=f[now][j]; //重要 for (j=0;j<=size[way[i].y];j++)  //儿子可以不修 for (l=size[now]-1;l>=j;l--)  //l=size[now]-1  i一定要修,把i的位置留出来了 f[now][l]=max(f[now][l],f[way[i].y][j]+g[l-j]); } }f[now][0]=0;  //i不修 for (i=size[now];i>=1;i--)f[now][i]=f[now][i-1]+v[now];     //i一定要修
}int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++){int u,w;scanf("%d%d",&u,&w);add(u,i);  //先修课 ,没有先修课的向root连边 v[i]=w;}m++;  //以0为根,0也选上了,所以总的选课数要++ dfs(0,0);doit(0,0,m); printf("%d",f[0][m]);return 0;
}

cv1378 选课(树)相关推荐

  1. 洛谷2014选课(树型dp)

    题目:https://www.luogu.org/problemnew/show/P2014 千万注意遍历 j 和 k 的边界! 0点很好用. siz很好用. #include<iostream ...

  2. 其他OJ 树型DP 选课

    在朱全民的PPT介绍的一个树型DP经典题,<选课>,中文题目,不结束 找了很久找到了可以提交的OJ,重庆八中 http://www.cqoi.net:2012/JudgeOnline/pr ...

  3. 智慧树怎么导入教务系统的课_智慧树网学习手册导入选课之APP版.doc

    智慧树网学习手册导入选课之APP版.doc 智慧树网学习手册 导入选课之APP版 目录 重要提醒2 一.登录2 ⒈ 新生登录-选课名单已导入2 ⒉ 新生登录-选课名单未导入4 3. 老生登录7 4. ...

  4. 智慧树怎么导入教务系统的课_西南交通大学希望学院 关于2019—2020学年春季学期公共任选课的选课通知...

    西南交通大学希望学院 关于2019-2020学年春季学期公共任选课的选课通知 院内各教学单位: 根据学院教务处教学工作安排,2019-2020春季学期公共任选课选课工作即将开始.由于当前正处于疫情防控 ...

  5. 树状dp(这个人写得好多转来慢慢看)

    树状动态规划定义 之所以这样命名树规,是因为树形DP的这一特殊性:没有环,dfs是不会重复,而且具有明显而又严格的层数关系.利用这一特性,我们可以很清晰地根据题目写出一个在树(型结构)上的记忆化搜索的 ...

  6. 为什么MySQL数据库要用B+树存储索引?

    小史是一个应届生,虽然学的是电子专业,但是自己业余时间看了很多互联网与编程方面的书,一心想进BAT互联网公司. 话说两个多月前,小史通过了A厂的一面,两个多月后的今天,小史终于等到了A厂的二面. 简单 ...

  7. mysql存储base64位用什么类型_【漫画】面试现场:为什么MySQL数据库要用B+树存储索引?...

    推荐阅读:MySQL最全整理(面试题+笔记+导图),面试大厂不再被MySql难倒! 小史是一个应届生,虽然学的是电子专业,但是自己业余时间看了很多互联网与编程方面的书,一心想进BAT互联网公司. 话说 ...

  8. 背包类树形DP 选课题解

    题目传送门; 我觉得题目给出0节点作为虚拟课程,也避免了我们要去想将若干个森林建成一棵树:将N个节点的森林建成了N+1条边的树: 其次,我们对这个题进行一个分析: 很容易想到F[x,t]表示以x为根的 ...

  9. 提高篇 第五部分 动态规划 第2章 树型动态规划

    例1 二叉苹果树 信息学奥赛一本通(C++版)在线评测系统 二叉苹果树_哔哩哔哩_bilibili 洛谷P2015 二叉苹果树 题目讲解 洛谷P2015 二叉苹果树 题目讲解_哔哩哔哩_bilibil ...

  10. python编写学生选课系统程序_python面向对象编程小程序- 选课系统

    选课系统 花了一晚上写的,可能还存在不足 1.程序框架 2.文件夹建立D:/选课系统 |___api | |___common_api.py |___bil | |___common.py |___c ...

最新文章

  1. 如何将本地数据库迁移到数据库上?
  2. 哪个学校计算机系学大物,计算机系各专业专业及名校介绍
  3. 运维基础(14)Mysql5.7 里4个数据库
  4. c语言程序设计教程岳莉答案,C++程序设计教程
  5. [蓝桥杯][基础练习VIP]分解质因数
  6. vue中多行文本标签_vue控制多行文字展开收起的实现示例
  7. pitr 原理_PostgeSQL 数据库备份与恢复实验 (PITR)
  8. oracle海量数据中提升创建索引的速度
  9. 《黑客X档案2007配套光盘》2007年上半年合集(6期)
  10. rls自适应滤波器matlab实现,Matlab自适应滤波器设计Demo——LMS,RLS
  11. npm常用命令(持续更新)
  12. excel替换指定列的文本
  13. 2022款Thinkphp家政上门预约系统-全开源系统源码
  14. [ Linux ] 可重入函数,volatile 关键字,SIGCHLD信号
  15. 扫描仪显示计算机无法,扫描仪无法显示怎么办 扫描仪无法显示解决方法【详解】...
  16. git add . 和 git add * 区别
  17. 贾扬清:如何看待人工智能方向的重要问题?
  18. 炫酷登录注册界面【超级简单 jQuery+JS+HTML+CSS实现】
  19. netstat的替代者-ss命令实例详解
  20. 拉卡拉支付的这些创新功能,你知道吗?

热门文章

  1. 【花雕动手做】有趣好玩的音乐可视化系列小项目(22)--LED无限魔方
  2. perfect forward secrecy
  3. 微软经典面试题(数字翻译为中文)
  4. 用GitHub做一份精美的在线简历
  5. gromacs 安装_Gromacs 4.0.3、4.5.5版安装方法
  6. linux 无法生成图片大小,简单点。表演()在Linux上的ImageJ中生成错误
  7. 谢烟客---------Linux之深入理解anaconda使用
  8. catti二级笔译综合能力真题_CATTI英语二级笔译综合能力试卷
  9. OV7725摄像头显示VGA/LCD
  10. 【0005】删除文件时,提示你需要权限才能执行此操作