【P1304】【P1305】选课与选课输出方案
多叉树归
原题:
学校实行学分制。每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分。学校开设了N(N<500)门的选修课程,每个学生可选课程的数量M是给定的。学生选修了这M门课并考核通过就能获得相应的学分。
在选修课程中,有些课程可以直接选修,有些课程需要一定的基础知识,必须在选了其它的一些课程的基础上才能选修。例如《Frontpage》必须在选修了《Windows操作基础》之后才能选修。我们称《Windows操作基础》是《Frontpage》的先修课。每门课的直接先修课最多只有一门。两门课也可能存在相同的先修课。每门课都有一个课号,依次为1,2,3,…。
你的任务是为自己确定一个选课方案,使得你能得到的学分最多,并且必须满足先修课优先的原则。假定课程之间不存在时间上的冲突。
(1≤N≤500)
思路根上一个差不多,不过这里可以把多叉转成2叉,用左儿子右兄弟
所以这里f[x][y]的意义有点不一样,表示涉及到x,x的兄弟,x的儿子的方案的最优值
这样搞的话搞法就是先搞一下兄弟,表示不选x,然后把f[x][y]的初值设成f[brother[x]][y],然后再搞兄弟和儿子一起搞的最优值
枚举i,先搞f[brother][i],再搞f[child[x]][y-i-1],然后更新答案
需要设置一个超级根,f[x][y]表示的是上面说的意义↑的话,需要从child[root]开始搞
也可以直接搞多叉的,比较直观,不过似乎不好写
怎么搞方案呐
似乎DP都是这么搞方案的:如果当前阶段的值等于最优值在这个阶段的值(求最优值的时候存下来了),这个阶段就在方案中
具体到这道题上,首先如果f[x][y]==f[brother[x]][y],说明x没用,直接搞brother[x],为什么看上面的求法↑
然后枚举i,如果f[x][y]==f[brother[x]][i]+f[child[x]][y-i-1]+value[x],就进去搞brother[x],i和child[x],y-i-1
直接贴输出方案的代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=,mark=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mark;
}
struct dcd{int child,brother,value;}tree[];
inline void insert_tree(int x,int y){
if(!tree[x].child) tree[x].child=y;
else{ tree[y].brother=tree[x].child; tree[x].child=y;}
}
int n,m;
int f[][];
bool have[];
void DP_tree(int x,int y){
if(f[x][y]) return ;
if(x==) return ; if(y==){ f[x][y]=; return ;}
DP_tree(tree[x].brother,y);//不选x,去搞brother
f[x][y]=max(f[x][y],f[tree[x].brother][y]);//别忘了还可以不选x选brother,这个要先处理一下
for(int i=;i<y;i++){
DP_tree(tree[x].brother,i);//搞brother,选i个
DP_tree(tree[x].child,y-i-);//搞child
f[x][y]=max(f[x][y],f[tree[x].brother][i]+f[tree[x].child][y-i-]+tree[x].value);
}
return ;
}
void get_have(int x,int y){
if(x== || y==) return ;
if(f[x][y]==f[tree[x].brother][y]) get_have(tree[x].brother,y);
else
for(int i=;i<y;i++)if(f[x][y]==f[tree[x].brother][i]+f[tree[x].child][y-i-]+tree[x].value){
get_have(tree[x].brother,i); get_have(tree[x].child,y-i-);
have[x]=true;
return ;
}
}
int main(){//freopen("ddd.in","r",stdin);
memset(tree,,sizeof(tree));
memset(have,,sizeof(have));
cin>>n>>m;
int _father;
for(int i=;i<=n;i++){
_father=read(); if(!_father) _father=n+; insert_tree(_father,i);//不设成0是因为还要判空
tree[i].value=read();
}
DP_tree(tree[n+].child,m);//不能从n+1开始,因为上面状态转移↑设定的是f[x][y]表示x自己和儿子和兄弟一起搞的最大值
cout<<f[tree[n+].child][m]<<endl;
get_have(tree[n+].child,m);
for(int i=;i<=n;i++)if(have[i]) cout<<i<<endl;
cout<<endl;
return ;
}
【P1304】【P1305】选课与选课输出方案的更多相关文章
- 『选课 树形dp 输出方案』
这道题的树上分组背包的做法已经在『选课 有树形依赖的背包问题』中讲过了,本篇博客中主要讲解将多叉树转二叉树的做法,以便输出方案. 选课 Description 学校实行学分制.每门的必修课都有固定的学 ...
- 新课程网上选课系统V1.0—适用于中小学校本课程选课、选修课选课
学校要开设选修课,人工选课实施了两年,耗时耗力,于是打算用网上选课,在网上搜索了一番,没多少实用的,有一个网上用的比较多的,功能太简单了,于是打算自己开发一个,功能参考了部分学校的功能,也有基于Aja ...
- 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase学生选课案例
实验目的 复习hbase的shell操作和javaAPI操作 了解javaWeb项目的MVC设计 学会dao(数据库访问对象)和service层的代码编写规范 学会设计hbase表格 实验原理 前面我 ...
- C#设计模式-外观模式
在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ”门面“模 ...
- Android Sqlite 实例入门
通过一个简单的例子来学习Sqlite,学生选课系统,一开始的需求是学生可以选课,选课完成后可以查询到已经选择的课. 首先设计三个表,学生,课程,选课.学生表存储学生的信息,课程表存储课程的信息,选课表 ...
- 在PowerDesigner中设计概念模型
原文:在PowerDesigner中设计概念模型 在概念模型中主要有以下几个操作和设置的对象:实体(Entity).实体属性 (Attribute).实体标识(Identifiers).关系(Rela ...
- entity framework core 支持批量插入,值得期待
entity framework6.x之前搞了这么多版本,构架这么牛B,居然没有批量插入更新的功能,但有很多替换的解决方案,例如Entity Framework Extended Library(ht ...
- SqlSever数据库实践周
资源下载 进行了为期5天的数据库设计,虽然以前用过数据库,但是这一次是使用书上规范的设计流程设计的数据库,感觉有必要记录一下,希望对其他人有帮助. 我的收获:在这个博客中会体现到我的收获,对于将要进行 ...
- 【Python&数据结构】 抽象数据类型 Python类机制和异常
这篇是<数据结构与算法Python语言描述>的笔记,但是大头在Python类机制和面向对象编程的说明上面.我也不知道该放什么分类了..总之之前也没怎么认真接触过基于类而不是独立函数的Pyt ...
随机推荐
- 银行支票和汇票中使用的专用字体MICR E13B条形码控件字体
MICR E13B条形码控件字体是一种在美国.加拿大.波多黎各.巴拿马.英国和其它少数国家的银行支票和汇票中使用的专用字体,主要用来打印适用于磁性和光学字符识别系统的MICR字符.MICR E13B条 ...
- 用腻了bootstrap的可以试试semantic-ui
semancti-ui介绍 semantic-ui是html/css框架的新贵,是继bootstrap和foundation之后的又一css神器.semantic-ui一出现在github上就受到火热 ...
- 移动设备和SharePoint 2013 - 第4部分:定位
博客地址:http://blog.csdn.net/foxdave 原文地址 在该系列文章中,作者展示了SharePoint 2013最显著的新功能概观--对移动设备的支持. 该系列文章: 移动设备和 ...
- JavaScript基础--超级玛丽(七)(上下左右控制)
相信大家都玩过超级玛丽,下面实现控制玛丽的上.下.左.右等基本功能,本篇只是在练习JavaScript的用法 1.创建一个HTML页面 <!doctype html> <html l ...
- oracle触发器如何使用2
触发器 是特定事件出现的时候,自动执行的代码块.类似于存储过程,但是用户不能直接调用他们.触发器是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处 ...
- IOS开发在线文档 记录下
View Programming Guide for iOS https://developer.apple.com/library/prerelease/ios/documentation/UIKi ...
- Qemu文档
http://wiki.qemu.org/Manual http://qemu.weilnetz.de/qemu-doc.html http://www.linuxcertif.com/man/1/q ...
- error: Apostrophe not preceded by \
解决方案为:在编译出错提示中找到相关的string.xml文档,在string标签中的字符串含有单引号(')前面,加上反斜杠(\)转义即可.
- 【Tsinghua OJ】隧道(Tunel)问题
描述 现有一条单向单车道隧道,每一辆车从隧道的一端驶入,另一端驶出,不允许超车 该隧道对车辆的高度有一定限制,在任意时刻,管理员希望知道此时隧道中最高车辆的高度是多少 现在请你维护这条隧道的车辆进出记 ...
- Mac OS X中配置Apache
我使用的Mac OS X版本是10.8.2,Mac自带了Apache环境. 启动Apache 设置虚拟主机 启动Apache 打开“终端(terminal)”,输入 sudo apachectl -v ...