[CTSC2001]1378 选课
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门课程的最大得分。
输入输出样例
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
13
各个测试点1s
分类标签 Tags 点此展开
分析:
根据题目描述我们可以知道这是个树形动规问题,但由于一个点可以有多个儿子,很难写出方程,所以我们想到将森林转二叉,之后再去做。
这里先补充一下多叉转二叉的知识,其规则是左儿子,右兄弟,即左子树上的都是儿子节点,右子树上的都是兄弟节点。这道题是森林,我们只需要虚拟零节点即可。我们要搜索的根就是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 选课的更多相关文章
- 树形DP+(分组背包||二叉树,一般树,森林之间的转换)codevs 1378 选课
codevs 1378 选课 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 学校实行学分制.每门的必修课都有固定的学分 ...
- codevs 1378 选课
题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...
- codevs 1378选课 树形DP
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; ],tr[] ...
- codevs 1378 选课 (树形DP)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; ][],f[] ...
- 树形dp练习
/*poj 1463 最小点覆盖 匈牙利*/ #include<iostream> #include<cstdio> #include<cstring> #defi ...
- 选课(codevs 1378)
题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...
- 从零开始学Python06作业思路:学生选课系统
一,作业要求 选课系统: 管理员: 创建老师:姓名.性别.年龄.资产 创建课程:课程名称.上课时间.课时费.关联老师 学生:用户名.密码.性别.年龄.选课列表[].上课记录{课程1:[di,a,]} ...
- python之选课系统详解[功能未完善]
作业需求 思路:1.先写出大体的类,比如学校类,学生类,课程类-- 2.写出类里面大概的方法,比如学校类里面有创建讲师.创建班级-- 3.根据下面写出大致的代码,并实现其功能 遇到的困 ...
- 第一章-第六题(帮人抢票,帮人选课这些软件是否合法 你怎么看?)--By梁旭晖
我觉得这些软件是合法的,符合道德规范的. 计算机当初设计的初衷就是简化甚至替代人类的工作.而软件作为计算机硬件的驱动着,其设计就是体现这些原则. 现在互联网上的订票,选课类型的网站还是有很多的,比如: ...
随机推荐
- scala函数返回值
1.使用returndef functionName ([参数列表]) : [return type] = { function body return [expr] } 2.直接把返回值写在最后: ...
- DotnetBrowser高级教程-(4)使用MVC框架4-过滤器
dotnetbrowser内置了过滤器,所谓过滤器,就是实现了Action前后拦截,请看下例: 1.增加目录Filters,在该目录下增加新的过滤器PerformanceFilter,代码如下: pu ...
- Java Enum的多态性
转载自:http://pf-miles.iteye.com/blog/187155 Enum+多态,我没说错,不过Enum是不可以被继承的,也不可以继承自别人,只是能实现接口而已,何谈多态?不过还是先 ...
- java中map的应用
map是键值对的集合接口,需要存储两个字段有联系的字段时可以使用这个. 1.查找字符串数组重复次数最多的字符串的重复次数 思路:使用map键值对存储,key值存数字符串,value存储出现的次数 Ma ...
- Solr 配置文件之schema.xml
schema.xml这个配置文件的根本目的是为了通过配置告诉Solr怎样建立索引. solr的数据结构例如以下: document:一个文档.一条记录 field:域.属性 solr通过搜索某个或某些 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程2.2 TwinCAT常见类型使用和转换_数组
声明和实例化数组的方法如下,你可以声明各种基本类型的数组 i: INT; array1: ARRAY [0..500] OF INT; FOR i := 0 TO 5000 DO arra ...
- Visual Studio 外请版本号管理插件 - AnkhSVN
Visual Studio 外请版本号管理插件 - AnkhSVN 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致 ...
- Laravel利用pusher推送消息
一.注册pusher 1.注册https://pusher.com/ 2.获取key,密匙,app_id等 二.配置pusher 1.安装pusher composer require pusher/ ...
- SQLite升级数据库:
SQLiteOpenHelper子类关键代码: SQLite升级数据库: SQLiteOpenHelper子类关键代码: public class MyDataHelper extends SQLit ...
- jquery插件:aotocomplete
aotocomplete.js http://blog.csdn.net/smeyou/article/details/7980273?_t_t_t=0.3565731019350138 $(func ...