luogu2014 选课 背包类树形DP
2024-08-31 07:17:50
题目大意:有N门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只有学完了课程a,才能学习课程b)。一个学生要从这些课程里选择M门课程学习,问他能获得的最大学分是多少?
对于每个节点u,定义u->DP[j]为在剩余课程数为j,以u为根的子树中能够获得的最高学分,则u->DP[j]=max{sum{v->DP[k] | sum[k]==j-1}|v∈u->Son}。
当u的子节点的子节点的DP值通过递归得出后,我们可以对u的每个DP[j]做一个背包。sum[k]==j-1提醒我们背包体积为j-1,k为物体的容量。DP求和提示我们DP[k]作为物体的价值。因为凑成j-1时每个v只选出一个v->DP[k],这提示我们背包按照子节点进行分组,物体最多选一个。这便是一个分组背包!之后将u->DP[j]=u->DP[j-1]+u->score.
注意:
- 分组背包的初值设置不要忘,DP[0]=0,其余为负无穷。
- 枚举k时要倒序循环,因为要考虑到物品的体积可能为0,如果正序循环,0最后处理,此时的DP[j]已经是更改后的值。
- DP[j]=DP[j-1]+score,而不是DP[j]=DP[j]+score
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cstdarg>
using namespace std; const int MAX_NODE = 310, MAX_V = MAX_NODE;
int totV, totNode; struct Node
{
int DP[MAX_V];
int Score;
int Id;
vector<Node*> Next;
}_nodes[MAX_NODE]; void AddEdge(int uId, int vId, int vScore)
{
Node *u = uId + _nodes, *v = vId + _nodes;
u->Id = uId;
v->Id = vId;
v->Score = vScore;
u->Next.push_back(v);
} void Dfs(Node *cur)
{
memset(cur->DP, 0xcf, sizeof(cur->DP));
cur->DP[0] = 0;
int sonCnt = cur->Next.size();
for (int i = 0; i < sonCnt; i++)
Dfs(cur->Next[i]);
for (int son = 0; son < sonCnt; son++)
for (int j = totV; j >= 0; j--)
for (int k = j; k >= 0; k--)
cur->DP[j] = max(cur->DP[j], cur->DP[j - k] + cur->Next[son]->DP[k]);
if(cur!=_nodes)
for (int j = totV; j > 0; j--)
cur->DP[j] = cur->DP[j - 1] + cur->Score;
} int Proceed()
{
Node *root = _nodes;
Dfs(root);
return root->DP[totV];
} int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
memset(_nodes, 0, sizeof(_nodes));
int u, score;
scanf("%d%d", &totNode, &totV);
for (int i = 1; i <= totNode; i++)
{
scanf("%d%d", &u, &score);
AddEdge(u, i, score);
}
printf("%d\n", Proceed());
return 0;
}
最新文章
- (转载)JAVA敏捷开发环境搭建
- django的跨站请求访问
- win7 64+python2.7.12安装numpy+scipy+matplotlib+scikit-learn
- Java编程思想学习(一) 一切都是对象
- C语言内存对齐详解(2)
- json、javaBean、xml互转的几种工具介绍 (转载)
- ZOJ 刷题记录 小黑屋 (`・д・&#180;)
- Python学习--09 模块
- ios framework 开发实战 之 参考
- 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)
- 简单的总结一下iOS面试中会遇到的问题
- 201521123050 《Java程序设计》第7周学习总结
- 秒杀系统HTML倒计时设置
- 【Codeforces Round】 #431 (Div. 2) 题解
- iOS设置截图背景图片透明
- django后台密码错误
- ORA-600 [kcblin_3] 解决方法
- python的标准库
- (精华)将json数组和对象转换成List和Map(小龙哥和牛徳鹤的对话)
- Java开篇
热门文章
- ReferenceEquals()、static Equals() 、instance Equals() 与 operator==之间的联系与区别
- Vue页面间传值,以及客户端数据存储
- 20小时掌握网站开发(免费精品htmlcss视频教程)
- python练习--1、简易登录接口
- CorelDRAW2019版本下载,CorelDRAW最新版新增功能(全)
- Java中RunTime.getRunTime().addShutdownHook用法
- javaee Properties键值对写入和读取方法
- 【剑指Offer】32、把数组排成最小的数
- GDI 映射模式(11)
- php第六讲