洛谷P2014 选课

题目描述

在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有N门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只有学完了课程a,才能学习课程b)。一个学生要从这些课程里选择M门课程学习,问他能获得的最大学分是多少?

输入输出格式

输入格式:

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

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

输出格式:

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

好困啊~~~

这道题做的不好。

一开始的做法:

​ 设\(f(i)(j)\)表示在以i为根的子树中,选择j个点并且一定选择i的最大价值。

​ 状态倒是设对了。但是转移就不会了。

​ 想的是树上的分组背包。

​ 将当前点的每个儿子看成一类物品,然后就可以枚举这一类物品中选多少个。

​ 应该是没问题,但是太困写不动了。。。

​ 而且我犯了一个错误就是对于当前的点u,应该枚举一层这个点的子树中选择多少个,所以我们应该记录当前的这个数的大小,并用其作为上界,但我是写了一个记忆化搜索每一次将传入的参数t当做上界,就不对了。

好了,感觉我的做法思路很乱套。

开始说一说正确做法吧。

​ 状态很好设:设\(f(i)(j)\)表示在以i为根的子树中,选择j个点并且一定选择i的最大价值。

​ 重点是怎么去推。

​ 这里用到了一个东西叫做多叉转二叉。也就是说我们要记录当前节点的子树大小作为枚举上界,所以我们可以每一次将当前点现在所枚举到的子树的大小加上,就是开一个变量记录当前的子树大小,在转移之前先将当前枚举到的子节点的size加上。

​ 这里有一个DP的思想,个人感觉类似记忆化搜索吧,挺重要的,就是我们当前要用v去转移u的状态,那么肯定的,我们应该知道v的状态(当然也可以在转移时记忆化搜索出v的状态),所以我们在转移u之前就应该先将v转移好。

#include<iostream>
#include<cstdio>
using namespace std;
const int wx=3017;
inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
return sum*f;
}
struct e{
int nxt,to;
}edge[wx*2];
int n,m,num,x;
int head[wx],a[wx],f[317][317],size[wx];
void add(int from,int to){
edge[++num].nxt=head[from];
edge[num].to=to;
head[from]=num;
}
int dfs(int u){
f[u][1]=a[u];int tot=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;tot+=dfs(v);
for(int j=tot;j>=1;j--){
for(int k=1;k<j;k++){
f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]);
}
}
}
return tot;
}
int main(){
n=read();m=read();
for(int i=1;i<=n;i++){
x=read();a[i]=read();
add(x,i);
}
dfs(0);
printf("%d\n",f[0][m+1]);
return 0;
}
//f[i][j]表示在以i为根的子树中选择j个点并且一定选i这个点的最大价值
//f[i][j]=max(f[i][j],f[v][k]+a[v]+f[i][j-k])

树形DP 洛谷P2014 选课的更多相关文章

  1. 洛谷 P2014 选课(树形背包)

    洛谷 P2014 选课(树形背包) 思路 题面:洛谷 P2014 如题这种有依赖性的任务可以用一棵树表示,因为一个儿子要访问到就必须先访问到父亲.然后,本来本题所有树是森林(没有共同祖先),但是题中的 ...

  2. 洛谷P2014 选课 (树形dp)

    10月1日更新.题目:在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分 ...

  3. 洛谷P2014 选课

    首先分析题目,这是一道树形dp的题目,是树形背包类的问题,以为每门课的先修课只有一门,所以这一定可以 构成一个森林结构,于是我们可以设计一个虚拟的根节点作为森林的根. 状态转移方程如下 dp[v][k ...

  4. 洛谷 P2014 选课

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...

  5. 洛谷 P2014 选课 && caioj 1108 树形动态规划(TreeDP)3:选课

    这里的先后关系可以看成节点和父亲的关系 在树里面,没有父亲肯定就没有节点 所以我们可以先修的看作父亲,后修的看作节点 所以这是一颗树 这题和上一道题比较相似 都是求树上最大点权和问题 但这道题是多叉树 ...

  6. 洛谷P2014——选课

    题目:https://www.luogu.org/problemnew/show/P2014 树状DP,注意枚举当前子树中选几个时的边界. 代码如下: #include<iostream> ...

  7. 洛谷—— P2014 选课

    https://www.luogu.org/problem/show?pid=2014 题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课 ...

  8. C++ 洛谷 2014 选课 from_树形DP

    洛谷 2014 选课 没学树形DP的,看一下. 首先要学会多叉树转二叉树. 树有很多种,二叉树是一种人人喜欢的数据结构,简单而且规则.但一般来说,树形动规的题目很少出现二叉树,因此将多叉树转成二叉树就 ...

  9. 洛谷$2014$ 选课 背包类树形$DP$

    luogu Sol 阶段和状态都是树形DP板子题,这里只讲一下背包的部分(转移)叭 它其实是一个分组背包模型,具体理解如下: 对于一个结点x,它由它的子结点y转移而来 在子结点y为根的树中可以选不同数 ...

随机推荐

  1. ashx页面缓存

    当用户访问页面时,整个页面将会被服务器保存在内存中,这样就对页面进行了缓存.当用户再次访问该页,页面不会再次执行数据操作,页面首先会检查服务器中是否存在缓存,如果缓存存在,则直接从缓存中获取页面信息, ...

  2. PHP把时间转换成几分钟前、几小时前、几天前的几个函数、类分享

    这篇文章主要介绍了php计算时间几分钟前.几小时前.几天前的几个函数.类分享,需要的朋友可以参考下一.函数实现实例1: <?php header("Content-type: text ...

  3. Struts2 - 配置文件详解

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "- ...

  4. OpenCV - Android Studio 中集成Opencv环境(包含opencv_contrib部分)

    我在上一篇博客中说到了在Android中集成OpenCV,但是那个版本的OpenCV是没有SIFT和SURF算法的,因为这些算法是受专利保护的,所以并没有被包含在预编译库中,所以如果想要使用SIFT和 ...

  5. Agc019_D Shift and Flip

    传送门 题目大意 给定两个长为$n$的$01$串$A,B$,每次操作有三种 将$A$整体向左移动,并将$A_1$放在原来$A_n$的位置上. 将$A$整体向有移动,并将$A_n$放在原来$A_1$的位 ...

  6. 每天一个linux命令(7):rmdir命令

    版权声明更新:2017-05-11博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的rmdir命令. ...

  7. CentOS 7关闭firewalld启用iptables

    在CentOS7中,有很多CentOS 6中的常用服务发生了变化. 其中iptables是其中比较大的一个.防火墙iptables被firewalld取代. 本文将介绍,如果采用systemctl关闭 ...

  8. HDFS中hsync方法介绍

    HDFS中hsync方法介绍 原创文章,转载请注明:博客园aprogramer 原文链接:HDFS中hsync方法介绍 1. 背景介绍 HDFS在写数据务必要保证数据的一致性与持久性,从HDFS最初的 ...

  9. 【256】◀▶IEW-答案

    附答案 Unit I Fast food Model Answers: Model 1 The pie chart shows the fast foods that teenagers prefer ...

  10. Packet for query is too large

    数据库:mysql5.6 framework: play framework 1.2.4 近日处理批量数据的insert,update,涉及的保存更新sql大概有18w.我的操作如下: 1)每次取10 ...