【题解】[JSOI2016] 最佳团体(分数规划)

P4322 JSOI2016 最佳团体 - 洛谷 (luogu.com.cn)

每个候选人 依赖 ,且 ,所以依赖关系形成一棵以 为根的树。

题目要求:如果选 ,就必须选 。这就是典型的树形依赖 dp,选子节点必须先选父节点。

但题目要最大化的是 不是直接最大化 ,所以不能直接背包,需要二分比值答案。


设计 dp 状态:dp[i][j] 表示从 dfs 序第 i 个位置开始,选 j 个节点的最大权值和。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 2510;

double S[N], P[N]; int R[N];
vector<int> G[N];
int dfn[N], tsp, id[N], siz[N];
int K, n;
double w[N], dp[N][N];
// dp[i][j] 表示从 dfs 序第 i 个位置开始,选 j 个节点的最大权值和

void dfs(int x) {
	dfn[x] = tsp;
	id[tsp] = x;
	tsp ++;
	siz[x] = 1;
	for (int y : G[x]) {
		dfs(y);
		siz[x] += siz[y];
	}
}

bool check(double x) {
	for (int i = 1; i <= n; i ++) {
		w[i] = P[i] - x * S[i];
	}
	w[0] = 0;
	for (int i = 0; i <= n + 1; i ++) {
		for (int j = 0; j <= K + 1; j ++) {
			dp[i][j] = -1e18;
		}
	}
	dp[n + 1][0] = 0;
	
	for (int i = n; i >= 0; i --) {   // 照 dfs 序从后往前遍历,也就是从叶子到根 
		int u = id[i];   // 当前 dfs 序对应的节点 
		for (int j = 0; j <= K + 1; j ++) {
			if (j >= 1) {
				dp[i][j] = max(dp[i][j], dp[i + 1][j - 1] + w[u]);
				// 当选了 u 节点,就可以从 u 的第一个孩子节点 i + 1 处转移 dp 
			}
			if (i + siz[u] <= n + 1) {
				dp[i][j] = max(dp[i][j], dp[i + siz[u]][j]);
				// 不选 u 节点,就只能从第一个不是 u 节点孩子转移,即跳过 u 的整个子树 
			}
			
			// 叶子节点没有孩子的特殊情况,上面两种分讨也包含了 
		}
	}
	/*
	假设某个叶子节点 v 被选中了
	在 dfs 序中,v 一定位于它所有祖先的子树区间内
	要从 dfs 序的起点走到 v,必须依次经过它的父节点、祖父节点......直到根

	在递推过程中,如果某个祖先 u 没有被选,那么根据情况一, 
	我们会直接跳过 u 的整个子树,根本不会进入 v 所在的区间
	因此 v 不可能被选中
	*/
	
	return (dp[0][K + 1] >= 0);   // 加上 0 就多选一个 
}

int main () {
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin >> K >> n;
	for (int i = 1; i <= n; i ++) {
		cin >> S[i] >> P[i] >> R[i];
		G[R[i]].push_back(i);
	}
	
	tsp = 0;
	dfs(0);
	
	double l = 0, r = 10000;
	// 小数点后三位精确,也就是 10000000 的精确度
	// 2 ^ 50 完全够   
	for (int i = 0; i <= 50; i ++) {
		double mid = (l + r) / 2;
		if (check(mid)) {
			l = mid;
		}
		else {
			r = mid;
		}
	}
	
	cout << fixed << setprecision(3) << l << "\n";
	
	
	return 0;
}
相关推荐
码流子1 小时前
2026 图像数据标注工具横评:LabelImg / CVAT / Label Studio / X-AnyLabeling / 国产Web平台,到底怎么选?
大数据·人工智能·算法
代码中介商1 小时前
C++ 预约系统实战(二):TCP + JSON 自定义协议设计
c++·网络协议
渡我白衣1 小时前
Util工具类功能设计与类设计
linux·服务器·网络·c++·人工智能·目标检测·机器学习
羊羊小栈1 小时前
基于「YOLO目标检测 + 多模态AI分析」的公共场所暴力安全智能检测分析预警系统
人工智能·算法·面试·毕业设计·大作业
小王的创意工坊1 小时前
C++ 在线判题平台(OJ)测试报告
c++·可用性测试
土星云SaturnCloud2 小时前
ResNet-50 图像分类算法在边缘微服务器上的部署与性能评测
服务器·人工智能·算法·边缘计算·resnet-50
Niuguangshuo2 小时前
文本-音频时间戳对齐:5 个开源工具实测
算法·开源·音视频
Niuguangshuo2 小时前
论文解读:RNN-Transducer,端到端流式 ASR 的骨架
算法·语音识别
sdm0704272 小时前
仿muduo库实现高并发服务器-下
开发语言·网络·c++·多路转接