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. 【iOS】UIButton 常用属性

    发现 UIButton 的相关属性不熟悉了……常用的一些属性代码如下: UIButton *add = [UIButton buttonWithType:UIButtonTypeCustom]; ad ...

  2. iOS 注释

    1) 参数的注释: UIButton *btnSend;/**< 发送按钮 */ 效果: 2) 方法的注释: type1(无参数): /** table 相关设置 */ -(void)confi ...

  3. spring cloud eureka + feign,api远程调用

    网上教程不少,有些就是复制粘贴,不结合实际生产. eureka不再阐述. 一般正常开发会有多个工程,且多个module. 我的习惯是: eureka server.权限.config.gateway ...

  4. (转)Linux LVM逻辑卷配置过程详解(创建、扩展、缩减、删除、卸载、快照创建)

    一.预备知识 LVM全称为Logical Volume Manager 逻辑卷管理器,LVM是Linux环境中对磁盘分区进行管理的一种机制,是建立在硬盘和分区之上.文件系统之下的一个逻辑层,可提高磁盘 ...

  5. 树莓派 + Windows IoT Core 搭建环境监控系统

    前言:Windows IoT 是微软为嵌入式开发板设计的一种物联网操作系统,运行Windows UWP(C# 开发),可以设计出丰富的交互界面,驱动GPIO,连接一些传感器做有意思的事,本文详细介绍如 ...

  6. 使用python画3D线条

    """用于验证整体趋势正确性""" #!python3 #-*- coding:utf-8 -*- import matplotlib as ...

  7. Unix-IO-同步,异步,阻塞,非阻塞-笔记篇

    概念更正 https://www.zhihu.com/question/19732473 错误的四个象限分类 https://www.ibm.com/developerworks/cn/linux/l ...

  8. cs231n---卷积网络可视化,deepdream和风格迁移

    本课介绍了近年来人们对理解卷积网络这个“黑盒子”所做的一些可视化工作,以及deepdream和风格迁移. 1 卷积网络可视化 1.1 可视化第一层的滤波器 我们把卷积网络的第一层滤波器权重进行可视化( ...

  9. C# 复制Excel单元格格式

    本文将介绍通过C# 复制Excel单元格格式的方法,包括复制单元格中的字体.字号.字体加粗.倾斜.单元格背景色.字体颜色.单元格数字格式.单元格文字方向.文字旋转.下划线.单元格对齐方式.单元格边框等 ...

  10. Selenium + python 测试环境搭建扩展-HTMLUNIT的使用

    尝试给公司的网站写每日例行检查的脚本时,不需要去打开浏览器,这是就用到HTMLUNIT的使用 HTMLUNIT是基于Selenium服务端的,所以需要selenium-server-standalon ...