[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梁旭晖
我觉得这些软件是合法的,符合道德规范的. 计算机当初设计的初衷就是简化甚至替代人类的工作.而软件作为计算机硬件的驱动着,其设计就是体现这些原则. 现在互联网上的订票,选课类型的网站还是有很多的,比如: ...
随机推荐
- 网易云音乐PC客户端加密API逆向解析
1.前言 网上已经有大量的web端接口解析的方法了,但是对客户端的接口解析基本上找不到什么资料,本文主要分析网易云音乐PC客户端的API接口交互方式. 通过内部的代理设置,使用fiddler作为代理工 ...
- android 小技巧
1. 模拟器横坚屏切换 ctrl + F11, ctrl + F12
- Highcharts使用二维数组生成图表
Highcharts使用二维数组生成图表 二维数组是更为灵活的一种数据存储方式.在Highcharts中.能够使用配置项column和rows二维数组.对于使用columns构建的二维数组,Highc ...
- STL学习笔记(第二章 C++及其标准程序库简介)
本章重点是介绍与C++标准程序库相关的几个最重要的语言新特性 template(模板) 程序库中几乎所有东西都被设计成template形式.所谓templates,是针对“一个或多个尚未明确的型别”所 ...
- 每天一个JavaScript实例-展示设置和获取CSS样式设置
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 【DB2】根据映射表映射出结果
第一步:创建语法 CREATE TABLE OLIVER_MAP(ID INT,COM_TYPE VARCHAR(100),COM_NAME VARCHAR(100),SR_UP DECIMAL(18 ...
- 【VAB】获取库文件地址
如何获取Excle库文件地址呢?具体代码如下: Public Sub 获取Excel库文件夹的路径() MsgBox "库文件夹的路径是: " & Application. ...
- LoadRunner调用md5方法
LoadRunner调用md5方法 上一篇 / 下一篇 2011-04-29 11:25:12 / 个人分类:Loadrunner 查看( 958 ) / 评论( 0 ) / 评分( 0 / 0 ) ...
- android实现免费短信验证
代码地址如下:http://www.demodashi.com/demo/12541.html 前言 获取短信验证码的的第三方很多,今天介绍一个获取短信验证码的demo,它有以下优势 短信到达率几乎1 ...
- Java jar转exe
http://www.blogjava.net/baoyaer/articles/97405.html Java转exe篇: 实现方式:Eclipse搭配JSmooth(免费). 1.先由Eclips ...