cogs 1199选课(树形dp 背包或多叉转二叉
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 背包或多叉转二叉的更多相关文章
- Codevs1378选课[树形DP|两种做法(多叉转二叉|树形DP+分组背包)---(▼皿▼#)----^___^]
题目描述 Description 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修 ...
- URAL_1018 Binary Apple Tree 树形DP+背包
这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...
- TYVJ P1051 选课 Label:多叉转二叉&&树形dp(虐心♥)
描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核通过就能获得 ...
- joyOI 选课 【树形dp + 背包dp】
题目链接 选课 题解 基础背包树形dp #include<iostream> #include<cstdio> #include<cmath> #include&l ...
- 『选课 树形dp 输出方案』
这道题的树上分组背包的做法已经在『选课 有树形依赖的背包问题』中讲过了,本篇博客中主要讲解将多叉树转二叉树的做法,以便输出方案. 选课 Description 学校实行学分制.每门的必修课都有固定的学 ...
- hdu1561 The more, The Better (树形dp+背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...
- codeforces 212E IT Restaurants(树形dp+背包思想)
题目链接:http://codeforces.com/problemset/problem/212/E 题目大意:给你一个无向树,现在用两种颜色去给这颗树上的节点染色.用(a,b)表示两种颜色分别染的 ...
- 选课 树形DP+多叉树转二叉树+dfs求解答案
问题 A: 选课 时间限制: 1 Sec 内存限制: 128 MB 题目描述 大 学里实行学分.每门课程都有一定的学分,学生只要选修了这门课并考核通过就能获得相应的学分.学生最后的学分是他选修的各门 ...
- BZOJ.1017.[JSOI2008]魔兽地图(树形DP 背包DP)
题目链接 树形DP,考虑子节点对父节点的贡献. 设f[x][i][j]表示当前为x,用i个x去合成上一层装备,花费为j的最大价值. 由子节点转移时 是一个分组背包,需要一个辅助数组g[i][j]表示前 ...
随机推荐
- Linux系统管理----磁盘管理与文件系统
1.为主机新增两块30GB的SCSI硬盘 找到要添加的虚拟机,单击鼠标右键,点击设置 点击添加 选择硬件类型,然后点击下一步 选择要创建的磁盘类型,然后点击下一步 指定要创建磁盘的容量,然后点击下一步 ...
- 【WPF】 InkCanvas 书写毛笔效果
首先贴出本文参考学习的文章吧. https://www.cnblogs.com/LCHL/p/9055642.html#4206298 感谢这位懒羊羊的代码和讲解(下简称羊博主),我在此基础上稍微加了 ...
- 最火的分布式 HTAP 数据库 TiDB - 入门实践教程
偶然在某篇博客看到了 TiDB,一个融合 OLTP 和 OLAP 的分布式开源数据库, GitHub 上 Star 很多,然后 watch 了,发现 commit 和 pull request 一直都 ...
- scroll-苹果滑动卡顿
2018年08月02日,程序小bug. 在移动端html中经常出现横向/纵向滚动的效果,但是在iPhone中滚动速度很慢,感觉不流畅,有种卡卡的感觉,但是在安卓设备上没有这种感觉; 一行代码搞定: - ...
- Vue项目的创建和UI资源
Vue项目创建打包与UI资源 1.Vue项目创建 1.1 vue-cli脚手架 vue-cli是一个基于vue的构建工具,用于搭建vue项目的环境,有着兼容,方便,快速的优点,能够完全遵循前后端分离的 ...
- spring boot中的声明式事务管理及编程式事务管理
这几天在做一个功能,具体的情况是这样的: 项目中原有的几个功能模块中有数据上报的功能,现在需要在这几个功能模块的上报之后生成一条消息记录,然后入库,在写个接口供前台来拉取消息记录. 看到这个需求,首先 ...
- Docker入门学习笔记
Docker 什么是Docker 虚拟化技术 在计算机中,虚拟化是一种资源管理技术,将计算机中的各种实体资源如:CPU.硬盘.内存等予以抽象.转换后呈现出来打破实体结构间的不可切割的障碍,使用户可以比 ...
- macOS 安装配置yaf框架 生成yaf项目
macOS 安装配置yaf框架 Yaf只支持PHP5.2及以上的版本. 并支持最新的PHP5.3.3 Yaf需要SPL的支持. SPL在PHP5中是默认启用的扩展模块 Yaf需要PCRE的支持. PC ...
- 图像反转(一些基本的灰度变换函数)基本原理及Python实现
1. 基本原理 获取像素值在[0, L]范围内的图像的反转图像,即为负片.适用于增强图像中白色或者灰色的区域,尤其当黑色在图片中占主地位时候 $$T(r) = L-r$$ 2. 运行结果 图源自ski ...
- C# Quartz结合控制台实现定时任务
前言: Quartz一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,基于C#写成,可应用于winform.asp.net.asp.net core应用中.提 ...