1378 选课

题目描述

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

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

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

输入输出格式

输入格式:

第一行有两个整数N,M用空格隔开。(1<=N<=200,1<=M<=150)

接下来的N行,第I+1行包含两个整数ki和si, ki表示第I门课的直接先修课,si表示第I门课的学分。若ki=0表示没有直接先修课(1<=ki<=N, 1<=si<=20)。

 
输出格式:

只有一行,选M门课程的最大得分。

输入输出样例

输入样例#1:

7  4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
输出样例#1:

13
数据范围及提示 Data Size & Hint

各个测试点1s

分类标签 Tags 点此展开

 
典型的树形背包(dp),希望读者能够认真理解并掌握。

分析:

根据题目描述我们可以知道这是个树形动规问题,但由于一个点可以有多个儿子,很难写出方程,所以我们想到将森林转二叉,之后再去做。

这里先补充一下多叉转二叉的知识,其规则是左儿子,右兄弟,即左子树上的都是儿子节点,右子树上的都是兄弟节点。这道题是森林,我们只需要虚拟零节点即可。我们要搜索的根就是f[0].left;

转化为二叉树之后,我们很容易就能写出方程f[i,j]表示以i为根的树,选了j门课能够得到的最大学分。

f[i,j]:=max{f[tree[i].left,k]+f[tree[i].right,j-1-k]+a[i],f[tree[i].right,j]}只和当前这门课选不选有关,这是很显然的,完全根据我们转换出的二叉树的定义和题目要求得来。

AC代码

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 1010
int n,m,f[N][N];
struct node{
int l,r,num;
}tree[N];
void init(){
scanf("%d%d",&n,&m);
for(int i=,x;i<=n;i++){
scanf("%d%d",&x,&tree[i].num);
if(!tree[x].l) tree[x].l=i;
else{
int t=tree[x].l;
while(tree[t].r) t=tree[t].r;
tree[t].r=i;
}
}
}
int dfs(int i,int m){
int tmp1,tmp2;
if(f[i][m]!=-) return f[i][m];
if(!i||!m) return f[i][m]=;
tmp1=dfs(tree[i].r,m);
for(int j=;j<m;j++){
tmp2=dfs(tree[i].l,j)+dfs(tree[i].r,m-j-)+tree[i].num;
if(tmp1<tmp2) tmp1=tmp2;
}
return f[i][m]=tmp1;
}
int main(){
memset(f,-,sizeof f);
init();
printf("%d\n",dfs(tree[].l,m));
return ;
}

-----------------------------------------------------------------------------------------------------------------------------------------------

华丽的分割线

------------------------------------------------------------------------------------------------------------------------------------------------

反思:

在树的儿子很多,很难处理时候,我们可以考虑多叉转二叉,或者森林转二叉。简化方程,只和当前节点选或者不选有关。特别注意,这样转的话会加大树的深度,也就是我们压栈的次数,数据范围极大时慎用。

记忆化搜索是解决树归的利器,注意记忆化搜索的框架,和打法。一定要注意细节。在函数中应有当前状态是否已知的判断,边界条件的处理(注意给数组赋值),根据方程枚举状态找最优,最后将求出的最优赋到数组中再返回值。

[CTSC2001]1378 选课的更多相关文章

  1. 树形DP+(分组背包||二叉树,一般树,森林之间的转换)codevs 1378 选课

    codevs 1378 选课 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond  题目描述 Description 学校实行学分制.每门的必修课都有固定的学分 ...

  2. codevs 1378 选课

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

  3. codevs 1378选课 树形DP

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ],tr[] ...

  4. codevs 1378 选课 (树形DP)

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; ][],f[] ...

  5. 树形dp练习

    /*poj 1463 最小点覆盖 匈牙利*/ #include<iostream> #include<cstdio> #include<cstring> #defi ...

  6. 选课(codevs 1378)

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

  7. 从零开始学Python06作业思路:学生选课系统

    一,作业要求 选课系统: 管理员: 创建老师:姓名.性别.年龄.资产 创建课程:课程名称.上课时间.课时费.关联老师 学生:用户名.密码.性别.年龄.选课列表[].上课记录{课程1:[di,a,]} ...

  8. python之选课系统详解[功能未完善]

    作业需求 思路:1.先写出大体的类,比如学校类,学生类,课程类--   2.写出类里面大概的方法,比如学校类里面有创建讲师.创建班级-- 3.根据下面写出大致的代码,并实现其功能       遇到的困 ...

  9. 第一章-第六题(帮人抢票,帮人选课这些软件是否合法 你怎么看?)--By梁旭晖

    我觉得这些软件是合法的,符合道德规范的. 计算机当初设计的初衷就是简化甚至替代人类的工作.而软件作为计算机硬件的驱动着,其设计就是体现这些原则. 现在互联网上的订票,选课类型的网站还是有很多的,比如: ...

随机推荐

  1. 摄像头bug查找工作总结

    近期花了很长时间在libcamera中查找和解决一个bug.下面将这段时间中的工作过程,以及对camera的认识总结如下: 首先是问题的发生,在UM2801中,摄像头的代码已经基本实现,并且相应功能也 ...

  2. Linux使用nginx部署Laravel

    问题描述 Laravel是PHP下当今最受欢迎的web应用开发框架,github上start数远超第二名Symfony,以前我用这个框架做项目的时候通常就是扔到apache里面,然后配置.htacce ...

  3. wp8使用mvvm模式简单例子(二)---登陆功能,事件触发

    首先,还是需要一个Model类来为UI层的元素提供数据源 public class LoginModel:DependencyObject { public string Uid { get { re ...

  4. GridView后台绑定数据列表方法

    在很多时候数据绑定都是知道了数据表中的表字段来绑定GridView控件的,那时候我就有个想法希望通过表明来查询数据库中的字段来动态的绑定GirdView控件数据并提供了相关的操作列,在网上找了一些资料 ...

  5. 关于angularjs dom渲染结束再执行的问题

    情景 当我点击了button, div才能显示.并且我想知道这个div的高度. 问题 当我点击这个button以后这个.chrome就然告诉我这个div高度是0.这不是睁着眼睛说瞎话吗?怎么能如此欺骗 ...

  6. How to check the 'OLE DB Destination' INPUT and OUTPUT

    Step 1: Step 2: Step 3:

  7. 基于Saltstatck实现页面实时显示tomcat启动日志(17)

    一.相关文件 master端: /srv/salt/tomcat/start.sls               #tomcat启动服务state.sls,须要自己创建 /srv/salt/tomca ...

  8. 将apache添加到服务

    拿apache为例 1.将应用程序放在PATH的任一个目录下,一般放在/usr/sbin/.执行下面命令 cp /usr/local/apache2/bin/httpd /usr/sbin/httpd ...

  9. iOS仿支付宝首页的刷新布局效果

    代码地址如下:http://www.demodashi.com/demo/12753.html XYAlipayRefreshDemo 运行效果 动画效果分析 1.UI需要变动,向上滑动的时候,顶部部 ...

  10. MATLAB 2014a 在Mac os x yosemite 10.10 Retina显示模糊的解决的方法

    恐怕非常多童鞋在升级了yosemite之后都遇到了Matlab的问题. 之前转载的一篇文章写了安装的方法,本文说一下解决Retina屏显示模糊的办法. 那么因为Matlab 2014a使用自带的jav ...