「COCI2016/2017 Contest #2」Bruza

解题思路 :

首先对于任意时刻 \(i\) ,硬币一定移动到了深度为 \(i\) 的节点,所以第 \(i\) 时刻 Danel 一定染掉一个深度为 \(i + 1\) 的节点。又因为如果硬币到了深度为 \(k\) 的节点游戏就结束了,所以深度 \(> k\) 的节点都可以忽视,把所有深度 \(= k\) 的节点看做这棵树的叶子,如果一个节点其子树里面没有深度 \(= k\) 的节点,那么这整棵子树也是可以被忽视的。

其次,如果染色的一个节点是另外一个节点的祖先,那么深度较深的那个节点被染是没有意义的。

那么每次染掉一个深度为 \(i\) 的节点,其至少会使得 \(k-i+1\) 个节点无法到达,那么染 \(k\) 次能染掉的节点数量的下界就是:

\[\sum_{i=1}^k k - i + 1= k(k+1)-\frac{k(k+1)}{2}=\frac{k(k+1)}{2}
\]

于是可以得到一个关于 \(k\) 的较松的上界,当满足时 Danel 必胜:

\[k \geq \sqrt{2n}
\]

实际上这个上界是比较松的,可以继续证明并加以利用。观察发现如果染掉一个没有分叉的节点,等价于染掉其子树中第一个有分叉的节点。那么可以除了根节点以外,每次染掉深度最小的一个有分叉的节点,且要保证任意时刻 \(i\) ,染掉的深度 \(\leq i\) 的节点个数必须 $\leq i $ 。

显然,如果每种深度的节点有分叉的仅有一个,那么Danel必胜。

假设在某一时刻出现两个深度最小为 \(d\) 且有分叉的节点,那么其中一个有分叉的节点不能被染掉。相当于转化为进入这个节点所对应的子树的一个子问题,而在这之前,通过染色使得不能到达的最少节点数量之和是:

\[\sum_{i=1}^d 2k - i =2kd-\frac{d(d+1)}{2}
\]

解释一下这个式子,假设之前的被染色的每一个节点都只有两个分叉,且这两个分叉对应的子树都是以两条链的形式存在的,这样显然是最少的情况,此时被减少至不能到达的部分就是该节点到根的路径以及这两个分叉。

令 \(S(n, k)\) 为初始状态的规模,此时进入的子问题的规模是 \(S(n', k')\) ,根据上述分析一下可以得到:

\[k' = k - d \\
n' = n - 2kd+\frac{d(d+1)}{2} \\
n' \leq n - 2kd + d^2
\]

在这里假设一个更小的上界使得当满足时 Danel 必胜:

\[k \geq \sqrt{n} \\
k^2 \geq n
\]

那么之前的式子

\[k' = k - d \\
n' \leq k^2 - 2kd + d^2 \\
n' \leq (k -d)^2
\]

此时 \(S(n',k')\) 仍然满足假设的上界 \(k \geq \sqrt{n}\) ,这里归纳证明得到了一个更小的上界当满足时 Danel 必胜。

把问题带回最初的贪心思路,第 \(i\) 次选择深度为 \(i+1\) 的节点一定是最优的,那么深度 \([2,k]\) 每种只能染最多一个节点,且最终要使得所有叶子都有一个祖先在染色的点集里面。

把问题转化到反dfn序上,令 \(dp(i, s)\) 表示反dfn序前 \(i\) 为已经选了深度集合为 \(s\) 的点能覆盖的最多叶子数量,为了防止对叶子的贡献重复计数,同一子树内不能同时选,那么转移的时候讨论一下就好了

\[dp(i, s) =\max(dp(i-1,s), dp(i-sz[i],s-2^{dep[i]})+val[i])
\]

其中 \(sz[i]\) 是反dfn序上第 \(i\) 位对应的节点的大小,\(val[i]\) 是这个节点的子树中的叶子节点数量,最后看一下是否存在一个 \(dp\) 状态能覆盖所有叶子即可,总复杂度 \(O(n2^\sqrt{n})\)。

据说还有 \(O(\sqrt{n}2^{\sqrt{n}})\) 的做法, 又据说一言难尽,改天再填坑吧。

code

/*program by mangoyang*/
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
} const int N = 405; vector<int> g[N];
int f[N][(1<<17)+2], vi[N][(1<<17)+2];
int sz[N], d[N], dfn[N], mx[N], h[N], leaf, n, k, cnt, all, tot; inline int MX(int x, int y){ return x > y ? x : y; } inline int solve(int u, int s){
if(~f[u][s]) return f[u][s];
if(s == all || u > cnt) return f[u][s] = 0;
if(u == 1 || (1 << d[u]) & s || mx[u] < k) return f[u][s] = solve(u + 1, s);
return f[u][s] = MX(solve(u + sz[u], s | (1 << d[u])) + h[u], solve(u + 1, s));
}
inline void dfs(int u, int fa){
dfn[u] = ++cnt; sz[dfn[u]] = 1;
if(u > 1) d[dfn[u]] = d[dfn[fa]] + 1;
mx[dfn[u]] = d[dfn[u]];
if(d[dfn[u]] == k) return (void) (leaf++, h[dfn[u]] = 1);
for(int i = 0; i < g[u].size(); i++){
int v = g[u][i];
if(v == fa) continue;
dfs(v, u), sz[dfn[u]] += sz[dfn[v]], h[dfn[u]] += h[dfn[v]];
mx[dfn[u]] = MX(mx[dfn[u]], mx[dfn[v]]);
}
}
int main(){
memset(f, -1, sizeof(f));
read(n), read(k), all = (1 << k) - 1;
if(k * k >= n) return puts("DA"), 0;
for(int i = 1, x, y; i < n; i++){
read(x), read(y);
g[x].push_back(y), g[y].push_back(x);
}
dfs(1, 0);
for(int i = 1; i <= n; i++) d[i]--;
puts(solve(1, 0) >= leaf ? "DA" : "NE");
return 0;
}

「COCI2016/2017 Contest #2」Bruza的更多相关文章

  1. loj #6250. 「CodePlus 2017 11 月赛」找爸爸

    #6250. 「CodePlus 2017 11 月赛」找爸爸 题目描述 小 A 最近一直在找自己的爸爸,用什么办法呢,就是 DNA 比对. 小 A 有一套自己的 DNA 序列比较方法,其最终目标是最 ...

  2. [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞

    [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞 试题描述 到河北省 见斯大林 / 在月光下 你的背影 / 让我们一起跳舞吧 うそだよ~ 河北省怎么可能有 Stalin. ...

  3. [LOJ 6249]「CodePlus 2017 11 月赛」汀博尔

    Description 有 n 棵树,初始时每棵树的高度为 H_i,第 i 棵树每月都会长高 A_i.现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于 L,而且木料必须是整棵树(即不 ...

  4. [LOJ 6248]「CodePlus 2017 11 月赛」晨跑

    Description “无体育,不清华”.“每天锻炼一小时,健康工作五十年,幸福生活一辈子” 在清华,体育运动绝对是同学们生活中不可或缺的一部分.为了响应学校的号召,模范好学生王队长决定坚持晨跑.不 ...

  5. 「JOISC 2017 Day 3」幽深府邸

    题解: 和hnoi2018day2t1基本一样 我想了半小时想出了一个很麻烦的做法 写了之后发现假掉了 刚开始想的是 先预处理出每个门要打开至少要在左边的哪个点$L[]$,右边的哪个点$R[]$ 对每 ...

  6. 「CodePlus 2017 11 月赛」Yazid 的新生舞会(树状数组/线段树)

    学习了新姿势..(一直看不懂大爷的代码卡了好久T T 首先数字范围那么小可以考虑枚举众数来计算答案,设当前枚举到$x$,$s_i$为前$i$个数中$x$的出现次数,则满足$2*s_r-r > 2 ...

  7. 「CodePlus 2017 11 月赛」大吉大利,晚上吃鸡!(dij+bitset)

    从S出发跑dij,从T出发跑dij,顺便最短路计数. 令$F(x)$为$S$到$T$最短路经过$x$的方案数,显然这个是可以用$S$到$x$的方案数乘$T$到$x$的方案数来得到. 然后第一个条件就变 ...

  8. 「CodePlus 2017 12 月赛」火锅盛宴(模拟+树状数组)

    1A,拿来练手的好题 用一个优先队列按煮熟时间从小到大排序,被煮熟了就弹出来. 用n个vector维护每种食物的煮熟时间,显然是有序的. 用树状数组维护每种煮熟食物的数量. 每次操作前把优先队列里煮熟 ...

  9. 「CodePlus 2017 12 月赛」可做题2(矩阵快速幂+exgcd+二分)

    昨天这题死活调不出来结果是一个地方没取模,凉凉. 首先有个一眼就能看出来的规律... 斐波那契数列满足$a_1, a_2, a_1+a_2, a_1+2a_2, 2a_1+3a_2, 3a_1+5a_ ...

随机推荐

  1. 2017ACM暑期多校联合训练 - Team 4 1003 HDU 6069 Counting Divisors (区间素数筛选+因子数)

    题目链接 Problem Description In mathematics, the function d(n) denotes the number of divisors of positiv ...

  2. HDU 1045 Fire Net (深搜)

    题目链接 Problem DescriptionSuppose that we have a square city with straight streets. A map of a city is ...

  3. redis笔记之两种持久化备份方式(RDB & AOF)

    Redis支持的两种持久化备份方式(RDB & AOF) redis支持两种持久化方式,一种是RDB,一种是AOF. RDB是根据指定的规则定时将内存中的数据备份到硬盘上,AOF是在每次执行命 ...

  4. idea docker 连接 linux 上的 docker

    安装插件 Docker插件,首先需要在你的IDEA中安装Docker插件,定位到File-Setting-Plugins后搜索Docker Integration安装 配置Docker服务器,在IDE ...

  5. Automation Testing - Best Practice(书写规范)

    Coding Standards Coding Standards are suggestions that will help us to write automation Scripts code ...

  6. PIP安装时报The repository located at pypi.douban.com is not a trusted or secure host and is being ignore

    C:\WINDOWS\system32>pip install scrapyCollecting scrapy The repository located at pypi.douban.com ...

  7. svn add --no-ignore

    提交新代码时:svn add --no-ignore  /dir   不加的话可能会漏提交某些依赖或文件. Svn st -q --no-ignore. 提交时不需要加

  8. slave->pxc后GTID不一致

    以下两个参数在两个节点是对得上的. | wsrep_last_applied | 3363764 | | wsrep_last_committed | 3363764 但show master sta ...

  9. c#操作pdf文件系列之创建文件

    1.我使用的工具是vs2013,引用的第三方程序集itextpdf 具体安装方法,可以通过nuget搜索iTextSharp然后进行安装. 2具体代码如下 创建两个不同pdf文件,每个地方什么意思代码 ...

  10. 84.Largest Rectangle in histogram---stack

    题目链接:https://leetcode.com/problems/largest-rectangle-in-histogram/description/ 题目大意:在直方图中找出最大的矩形面积.例 ...