Description

给定一棵 \(n\) 个节点的树,点有点权 \(a_u\),可能为负。现在请你在树上找出 \(k~(1~\leq~k~\leq~n)\) 个不相交集合,使得每个集合中的每对点都可以通过本集合中的点互相到达,假设选出的 \(k\) 个集合的并集为 \(s\),要求最大化:

\[\frac{\sum_{u \in s} a_u}{k}
\]

如果有多解请输出 \(k\) 最大的解

Input

第一行是节点个数 \(n\)。

下面一行 \(n\) 个数代表点权

下面 \(n - 1\) 行描述这棵树

Output

输出一行两个整数,分别是选出的点权和以及 \(k\)

不约分

Solution

结论:在不限元素个数时,要求选出元素的平均值最大,则最优解一定为只选择元素值最大的元素。如果有多个元素的值最大,选择个数对答案无影响。

证明:数学归纳法,先将元素按照权值降序排序。当只选择 \(1\) 个元素的时候,显然选择第一个元素最优。考虑已经选了 \(k\) 个元素,现在要决定是否选 \(k + 1\) 个元素。由于是降序排序的,则这个元素的权值显然不大于前面所有元素的平均值。设前面所有元素的平均值为 \(a\),第 \(k + 1\) 个元素的权值为 \(w\),则选择该元素后的平均值为 \(\frac{ak + w}{k + 1}\) 。要判断它和原平均值 \(a\) 的关系,则对它们做差,记 \(\delta~=~\frac{ak + w}{k + 1} - a\)

\[\delta~=~\frac{ak}{k + 1} + \frac{w}{k + 1}- \frac{a(k + 1)}{k + 1}~=~\frac{w}{k + 1} - \frac{a}{k + 1}~=~\frac{w - a}{k + 1}
\]

前面已经论证 \(w~\leq~a\),于是 \(\delta~\leq~0\)。当且仅当 \(w~=~a\) 即前 \(k + 1\) 个元素权值相同时,等号成立。证毕。

于是根据这个结论,问题就被转化成了:求一个符合要求的集合使得这个集合的权值和尽可能大,然后统计有多少个这样的不想交的集合。

第一问显然可以直接树形DP,设 \(f_u\) 为 \(u\) 的子树中必选 \(u\) 的集合的最大权值,则有:

\[f_u~=~\sum_{to} \max(f_{to}, 0)
\]

于是就可以求出最大的权值了。考虑统计答案时,由于要求的是不相交的集合,所以我们每将一个集合加入贡献以后再将这个集合删掉,一边统计答案一遍DP就可以了。

Code

#include <cstdio>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#define putchar(o) \
puts("I am a cheater!")
#endif
#define rg register
#define ci const int
#define cl const long long typedef long long int ll; namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
} template <typename T>
inline void qr(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
} template <typename T>
inline void ReadDb(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
} namespace OPT {
char buf[120];
} template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
rg int top=0;
do {OPT::buf[++top] = char(x % 10 + '0');} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
} const int maxn = 300010;
const int maxm = 600010; struct Edge {
int to;
Edge *nxt;
};
Edge edge[maxm], *hd[maxn];int ecnt;
inline void cont(ci from, ci to) {
Edge &e = edge[++ecnt];
e.to = to; e.nxt = hd[from]; hd[from] = &e;
} int n, cnt;
ll ans = -(1ll << 62);
ll MU[maxn], frog[maxn]; void reading();
void dfs(ci, ci, ci); int main() {
freopen("1.in", "r", stdin);
qr(n);
for (rg int i = 1; i <= n; ++i) qr(MU[i]);
reading();
dfs(1, 0, 1); dfs(1, 0, 0);
qw(ans * cnt, ' ', true); qw(cnt, '\n', true);
return 0;
} void reading() {
int a, b;
for (rg int i = 1; i < n; ++i) {
a = b = 0; qr(a); qr(b);
cont(a, b); cont(b, a);
}
} void dfs(ci u, ci fa, ci op) {
frog[u] = MU[u];
for (Edge *e = hd[u]; e; e = e->nxt) {
int &to = e->to;
if (to == fa) continue;
dfs(to, u, op);
if (frog[to] > 0) frog[u] += frog[to];
}
if (op) ans = std::max(ans, frog[u]);
else if (frog[u] == ans) ++cnt, frog[u] = -(1ll << 60);
}

Summary

选择任意个元素使得平均值最大时,只选择最大的就好啦

【数学/贪心/DP】【CF1088E】 Ehab and a component choosing problem的更多相关文章

  1. cf1088E Ehab and a component choosing problem (树形dp)

    题意(考试时看错了对着样例wa了好久..):从树上选k个连通块,使得权值的平均值最大的基础上,选的块数最多 如果不考虑块数最多的限制,肯定是只选一个权值最大的块是最好的 然后只要看这个权值最大的块有多 ...

  2. Codeforces 1088E Ehab and a component choosing problem

    Ehab and a component choosing problem 如果有多个连接件那么这几个连接件一定是一样大的, 所以我们先找到值最大的连通块这个肯定是分数的答案. dp[ i ]表示对于 ...

  3. Codeforces Round #525 (Div. 2)E. Ehab and a component choosing problem

    E. Ehab and a component choosing problem 题目链接:https://codeforces.com/contest/1088/problem/E 题意: 给出一个 ...

  4. Codeforces Round #525 (Div. 2) E. Ehab and a component choosing problem 数学

    题意:给出树 求最大的sigma(a)/k k是选取的联通快个数   联通快不相交 思路: 这题和1个序列求最大的连续a 的平均值  这里先要满足最大平均值  而首先要满足最大  也就是一个数的时候可 ...

  5. cfE. Ehab and a component choosing problem(贪心)

    题意 题目链接 给出一棵树,每个节点有权值,选出\(k\)个联通块,最大化 \[\frac{\sum_{i \in S} a_i}{k}\] Sol 结论:选出的\(k\)个联通块的大小是一样的且都等 ...

  6. Codeforces Round #525 E - Ehab and a component choosing problem

    题目大意: 在一棵树中 选出k个联通块 使得 这k个联通块的点权总和 / k 最大 并且这k个联通块不相互覆盖(即一个点只能属于一个联通块) 如果有多种方案,找到k最大的那种 给定n 有n个点 给定n ...

  7. 【BZOJ-3174】拯救小矮人 贪心 + DP

    3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 686  Solved: 357[Submit][Status ...

  8. BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP

    BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...

  9. 洛谷P4823 拯救小矮人 [TJOI2013] 贪心+dp

    正解:贪心+dp 解题报告: 传送门! 我以前好像碰到过这题的说,,,有可能是做过类似的题qwq? 首先考虑这种显然是dp?就f[i][j]:决策到了地i个人,跑了j个的最大高度,不断更新j的上限就得 ...

随机推荐

  1. 转载:XGBOOST算法梳理

    学习内容: CART树 算法原理 损失函数 分裂结点算法 正则化 对缺失值处理 优缺点 应用场景 sklearn参数 转自:https://zhuanlan.zhihu.com/p/58221959 ...

  2. Mysql数据库的隔离级别

    Mysql数据库的隔离级别有四种 1.read umcommitted   读未提交(当前事务可以读取其他事务没提交的数据,会读取到脏数据) 2.read committed 读已提交(当前事务不能读 ...

  3. Python set 集合

    简介 python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联 合), intersection(交), difference ...

  4. 将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结

    将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目.又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native ...

  5. 让CentOS在同一个窗口打开文件夹

    http://www.linuxidc.com/Linux/2010-04/25756.htm

  6. M1个人贡献分以及转会确定

    按照之前的方案,团队成员得分统计表见下:   P(Pd*pf) 比重 个人得分 黎柱金 335400 0.1844 63 晏旭瑞 306000 0.1682 59 孙思权 304150 0.1672 ...

  7. Monty Hall 问题与贝叶斯定理的理解

     三门问题(Monty Hall problem),是一个源自博弈论的数学游戏问题,大致出自美国的电视游戏节目Let's Make a Deal.问题的名字来自该节目的主持人蒙提·霍尔(Monty H ...

  8. vue router 几种方式对比 (转载)

    <div id="app"> <h1>Hello App!</h1> <p> <!-- 使用 router-link 组件来导 ...

  9. 初期测评 A 排序

    https://vjudge.net/contest/240302#problem/A 输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用空格分割的若干非负整数(可能有些整数以‘0 ...

  10. set_magic_quotes_runtime

    在php的配置文件中,有个布尔值的设置,就是magic_quotes_runtime,当它打开时,php的大部分函数自动的给从外部引入的(包括数据库或者文件)数据中的溢出字符加上反斜线. 当然如果重复 ...