http://cogs.pro:8080/cogs/problem/problem.php?pid=vQyiJkkPP

题意:给m门课,每门课在上完其先修课后才能上,要你从中选n门课使得总学分尽可能大。

思路:背包,没有先修课看成其先修课编号为0,求一个f[0][n]的背包,表示以0为根的树选n个结点的最大总权值,设x为根,y为x的孩子,对每个孩子,dfs(y),然后f[[x][t]=max(f[x][t],f[x][t-j]+f[y][j])用每个孩子更新x,最后若x不是0,再用自己的权值更新自己。但背包好像不能记录路径。

 #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
const int MAXN=;
int read(){
int sum=,flag=;
char c;
for(;c<''||c>'';c=getchar())if(c=='-') flag=-;
for(;c>=''&&c<='';c=getchar())sum=(sum<<)+(sum<<)+c-'';
return sum*flag;
}
int n,m;
int v[MAXN];
vector<int>son[MAXN];
int f[MAXN][MAXN];
void init(){
n=read();m=read();
rep(i,,n){
int y;
y=read();v[i]=read();
son[y].push_back(i);
}
}
void DP(int x){
f[x][]=;
for(int i=;i<son[x].size();++i){
int y=son[x][i];
DP(y);
dep(t,m,)
dep(j,t,)
if(t>=j)
f[x][t]=max(f[x][t],f[x][t-j]+f[y][j]);
}
if(x!=) dep(t,m,) f[x][t]=f[x][t-]+v[x];
}
int main(){
init();
DP();
printf("%d",f[][m]);
return ;
}

多叉转二叉,左孩子右兄弟。

若选根结点,f[i][j] = f[br[i][j]

若不选根结点,f[i][j] = f[ch[i]][k]+f[br[i]][j-1-k]+v[i]

递归寻找路径方法类似。

 #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
const int MAXN=;
int read(){
int sum=,flag=;
char c;
for(;c<''||c>'';c=getchar())if(c=='-') flag=-;
for(;c>=''&&c<='';c=getchar())sum=(sum<<)+(sum<<)+c-'';
return sum*flag;
}
int n,m;
int v[MAXN];
int br[MAXN],ch[MAXN];
bool ans[MAXN];
int f[MAXN][MAXN];
void init(){
n=read();m=read();
int x;
rep(i,,n){
x=read();
v[i]=read();
if(!x) x=n+;
br[i]=ch[x];
ch[x]=i;
}
memset(f,-,sizeof f);
}
void DP(int x,int y){
if(f[x][y]>=) return;
if(!x||!y) {f[x][y]=;return;}
DP(br[x],y);
rep(i,,y-){
DP(br[x],i);
DP(ch[x],y-i-);
f[x][y]=max(f[x][y],max(f[br[x]][y],f[br[x]][i]+f[ch[x]][y-i-]+v[x]));
}
}
void path(int x,int y){
if(!x||!y) return;
if(f[x][y]==f[br[x]][y]) path(br[x],y);
else {
rep(i,,y-){
if(f[x][y]==f[br[x]][i]+f[ch[x]][y-i-]+v[x]){
path(br[x],i);
path(ch[x],y-i-);
ans[x]=;
return;
}
}
}
}
int main(){
init();
DP(ch[n+],m);
printf("%d\n",f[ch[n+]][m]);
path(ch[n+],m);
rep(i,,n) if(ans[i]) printf("%d\n",i);
return ;
}

cogs 1199选课(树形dp 背包或多叉转二叉的更多相关文章

  1. Codevs1378选课[树形DP|两种做法(多叉转二叉|树形DP+分组背包)---(▼皿▼#)----^___^]

    题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...

  2. URAL_1018 Binary Apple Tree 树形DP+背包

    这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...

  3. TYVJ P1051 选课 Label:多叉转二叉&&树形dp(虐心♥)

    描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核通过就能获得 ...

  4. joyOI 选课 【树形dp + 背包dp】

    题目链接 选课 题解 基础背包树形dp #include<iostream> #include<cstdio> #include<cmath> #include&l ...

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

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

  6. hdu1561 The more, The Better (树形dp+背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...

  7. codeforces 212E IT Restaurants(树形dp+背包思想)

    题目链接:http://codeforces.com/problemset/problem/212/E 题目大意:给你一个无向树,现在用两种颜色去给这颗树上的节点染色.用(a,b)表示两种颜色分别染的 ...

  8. 选课 树形DP+多叉树转二叉树+dfs求解答案

    问题 A: 选课 时间限制: 1 Sec  内存限制: 128 MB 题目描述 大 学里实行学分.每门课程都有一定的学分,学生只要选修了这门课并考核通过就能获得相应的学分.学生最后的学分是他选修的各门 ...

  9. BZOJ.1017.[JSOI2008]魔兽地图(树形DP 背包DP)

    题目链接 树形DP,考虑子节点对父节点的贡献. 设f[x][i][j]表示当前为x,用i个x去合成上一层装备,花费为j的最大价值. 由子节点转移时 是一个分组背包,需要一个辅助数组g[i][j]表示前 ...

随机推荐

  1. BGP属性控制实验

    目录 实验拓扑 实验需求 实验步骤 个人小结: 实验拓扑 实验需求 更改BGP路由的属性让R4访问R1优先选R2这条路 实验步骤 1. 按照图示配置IP地址及环回口地址 R1 [R1]int g0/0 ...

  2. Git 服务使用搭建集合

    Git 服务使用搭建集合 一.本地Git 仓库搭建与使用 1.Git 概念介绍 版本控制系统 版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统.大部分时候我们使用最频繁的还是对源 ...

  3. Java虚拟机详解(四)------垃圾收集器

    上一篇博客我们介绍了Java虚拟机垃圾回收,介绍了几种常用的垃圾回收算法,包括标记-清除,标记整理,复制等,这些算法我们可以看做是内存回收的理论方法,那么在Java虚拟机中,由谁来具体实现这些方法呢? ...

  4. Go中配置文件读取的几种方式

    日常开发中读取配置文件包含以下几种格式: json 格式字符串 K=V 键值对 xml 文件 yml 格式文件 toml 格式文件 前面两种书写简单,解析过程也比较简单.xml形式书写比较累赘,yml ...

  5. JAVA MQ API方式通信采用Binding MQ Server方式

    package com.mqapi;   /**  * @modified by actorai E-mail:actorai@163.com  * @version 创建时间:2010-9-15 * ...

  6. Linux:oracle11.2.0dbca静默建库

    1.关闭防火墙 systemctl stop firewalld.service #停止firewall systemctl disable firewalld.service #禁止firewall ...

  7. gcd 和 同余方程(Exgcd)

    求关于x的同余方程 ax≡1(mod b) 的最小正整数解. 对于 100%的数据,2≤a,b≤2*109. NOIP 2012 提高组 第二天 第一题 (只看Exgcd的自行跳过这段文字) 先撇开扩 ...

  8. Golang 解决 Iris 被墙的依赖包

    使用 Golang 的 Iris web 框架时,用 go get github.com/kataras/iris 命令久久无法下载,最后还报一堆错误. 使用  GOPROXY 可解决问题,也可参考如 ...

  9. java并发系列 - 第28天:实战篇,微服务日志的伤痛,一并帮你解决掉

    这是java高并发系列第28篇文章. 环境:jdk1.8. 本文内容 日志有什么用? 日志存在的痛点? 构建日志系统 日志有什么用? 系统出现故障的时候,可以通过日志信息快速定位问题,修复bug,恢复 ...

  10. Java 内存模型和 JVM 内存结构真不是一回事

    这两个概念估计有不少人会混淆,它们都可以说是 JVM 规范的一部分,但真不是一回事!它们描述和解决的是不同问题,简单来说, Java 内存模型,描述的是多线程允许的行为 JVM 内存结构,描述的是线程 ...