多叉树归

原题:

学校实行学分制。每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分。学校开设了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

直接贴输出方案的代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. using namespace std;
  7. int read(){int z=,mark=; char ch=getchar();
  8. while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
  9. while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
  10. return z*mark;
  11. }
  12. struct dcd{int child,brother,value;}tree[];
  13. inline void insert_tree(int x,int y){
  14. if(!tree[x].child) tree[x].child=y;
  15. else{ tree[y].brother=tree[x].child; tree[x].child=y;}
  16. }
  17. int n,m;
  18. int f[][];
  19. bool have[];
  20. void DP_tree(int x,int y){
  21. if(f[x][y]) return ;
  22. if(x==) return ; if(y==){ f[x][y]=; return ;}
  23. DP_tree(tree[x].brother,y);//不选x,去搞brother
  24. f[x][y]=max(f[x][y],f[tree[x].brother][y]);//别忘了还可以不选x选brother,这个要先处理一下
  25. for(int i=;i<y;i++){
  26. DP_tree(tree[x].brother,i);//搞brother,选i个
  27. DP_tree(tree[x].child,y-i-);//搞child
  28. f[x][y]=max(f[x][y],f[tree[x].brother][i]+f[tree[x].child][y-i-]+tree[x].value);
  29. }
  30. return ;
  31. }
  32. void get_have(int x,int y){
  33. if(x== || y==) return ;
  34. if(f[x][y]==f[tree[x].brother][y]) get_have(tree[x].brother,y);
  35. else
  36. for(int i=;i<y;i++)if(f[x][y]==f[tree[x].brother][i]+f[tree[x].child][y-i-]+tree[x].value){
  37. get_have(tree[x].brother,i); get_have(tree[x].child,y-i-);
  38. have[x]=true;
  39. return ;
  40. }
  41. }
  42. int main(){//freopen("ddd.in","r",stdin);
  43. memset(tree,,sizeof(tree));
  44. memset(have,,sizeof(have));
  45. cin>>n>>m;
  46. int _father;
  47. for(int i=;i<=n;i++){
  48. _father=read(); if(!_father) _father=n+; insert_tree(_father,i);//不设成0是因为还要判空
  49. tree[i].value=read();
  50. }
  51. DP_tree(tree[n+].child,m);//不能从n+1开始,因为上面状态转移↑设定的是f[x][y]表示x自己和儿子和兄弟一起搞的最大值
  52. cout<<f[tree[n+].child][m]<<endl;
  53. get_have(tree[n+].child,m);
  54. for(int i=;i<=n;i++)if(have[i]) cout<<i<<endl;
  55. cout<<endl;
  56. return ;
  57. }

【P1304】【P1305】选课与选课输出方案的更多相关文章

  1. 『选课 树形dp 输出方案』

    这道题的树上分组背包的做法已经在『选课 有树形依赖的背包问题』中讲过了,本篇博客中主要讲解将多叉树转二叉树的做法,以便输出方案. 选课 Description 学校实行学分制.每门的必修课都有固定的学 ...

  2. 新课程网上选课系统V1.0—适用于中小学校本课程选课、选修课选课

    学校要开设选修课,人工选课实施了两年,耗时耗力,于是打算用网上选课,在网上搜索了一番,没多少实用的,有一个网上用的比较多的,功能太简单了,于是打算自己开发一个,功能参考了部分学校的功能,也有基于Aja ...

  3. 吴裕雄--天生自然HADOOP操作实验学习笔记:hbase学生选课案例

    实验目的 复习hbase的shell操作和javaAPI操作 了解javaWeb项目的MVC设计 学会dao(数据库访问对象)和service层的代码编写规范 学会设计hbase表格 实验原理 前面我 ...

  4. C#设计模式-外观模式

    在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ”门面“模 ...

  5. Android Sqlite 实例入门

    通过一个简单的例子来学习Sqlite,学生选课系统,一开始的需求是学生可以选课,选课完成后可以查询到已经选择的课. 首先设计三个表,学生,课程,选课.学生表存储学生的信息,课程表存储课程的信息,选课表 ...

  6. 在PowerDesigner中设计概念模型

    原文:在PowerDesigner中设计概念模型 在概念模型中主要有以下几个操作和设置的对象:实体(Entity).实体属性 (Attribute).实体标识(Identifiers).关系(Rela ...

  7. entity framework core 支持批量插入,值得期待

    entity framework6.x之前搞了这么多版本,构架这么牛B,居然没有批量插入更新的功能,但有很多替换的解决方案,例如Entity Framework Extended Library(ht ...

  8. SqlSever数据库实践周

    资源下载 进行了为期5天的数据库设计,虽然以前用过数据库,但是这一次是使用书上规范的设计流程设计的数据库,感觉有必要记录一下,希望对其他人有帮助. 我的收获:在这个博客中会体现到我的收获,对于将要进行 ...

  9. 【Python&数据结构】 抽象数据类型 Python类机制和异常

    这篇是<数据结构与算法Python语言描述>的笔记,但是大头在Python类机制和面向对象编程的说明上面.我也不知道该放什么分类了..总之之前也没怎么认真接触过基于类而不是独立函数的Pyt ...

随机推荐

  1. Power Point已经检测到你的显卡可能无法正确配置

    Microsoft PowerPoint打开ppt时提示信息 PowerPoint已检测到你的显卡可能无法正确配置最佳的幻灯片播放体验(“Power Point has detected that y ...

  2. HTML--2图片热点,网页划区,拼接

    图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果. 示例: 网页划区: 在一个网页里,规划出一个区域用来展示另一个网页的内容. 示例: 网页的拼接: 在一个网络 ...

  3. 一个很好介绍js的例子

    function UpdateInit(opt){ this.init(opt);} UpdateInit.prototype={ loadUrl:null, loadParam:null, befo ...

  4. redis补充和rabbitmq讲解

    线程池: redis发布订阅: rabbitMQ: MySQL; python pymysql: python orm SQLAchemy: paramiko: 堡垒机: 1.线程池 1.1 cont ...

  5. UITableView错误 ‘unable to dequeue a cell with identifier Cell'

    - (id)dequeueReusableCellWithIdentifier:(NSString *)identifier; - (id)dequeueReusableCellWithIdentif ...

  6. 使用copy来拷贝对象

    拷贝对象 您通过将 copy 消息发送给对象,以制作对象的副本. NSArray *myArray = [yourArray copy]; 要拷贝,接收对象的类必须遵守 NSCopying 协议.如果 ...

  7. webservice basics

    =====================Quote starts================== JAX-WS (JavaTM API for XML-Based Web Services)规范 ...

  8. JLOI2010 冠军调查 最小割

    var b,f:..] of longint; s,t,i,j,n,m,x,y:longint; l,h:..]of longint; a:..,..]of longint; procedure bf ...

  9. 分布式系统之CAP理论杂记[转]

    分布式系统之CAP理论杂记 http://www.cnblogs.com/highriver/archive/2011/09/15/2176833.html 分布式系统的CAP理论: 理论首先把分布式 ...

  10. 转:Enterprise Library 4.0缓存应用程序块

    英文原文:http://msdn.microsoft.com/zh-cn/library/cc511588(en-us).aspx Enterprise Library 缓存应用程序块允许开发人员在应 ...