题解-CF429C Guess the Tree
题面
给一个长度为 \(n\) 的数组 \(a_i\),问是否有一棵树,每个节点要么是叶子要么至少有两个儿子,而且 \(i\) 号点的子树大小是 \(a_i\)。
数据范围:\(1\le n\le 24\)。
题解
发现 \(n\) 很小,想到可以状压。
设叶子节点有 \(ln\) 个,所以中间节点有 \(mn=n-ln\) 个。
由于“每个节点要么是叶子要么至少有两个儿子”,所以 \(ln\ge\lceil\frac n2\rceil\),\(mn\le n-\lceil\frac n2\rceil \le 11\)。
所以可以先特判 \(2mn\ge n\) 的情况答案为 NO
。
然后剩下的可以 dp
,设 \(f_{t,s,i}\):
\(t\) 表示是一棵森林还是一个子树(为了对付“每个节点要么是叶子要么至少有两个儿子”,如果是子树 \(t=0\),否则 \(t=1\))。
\(s\) 表示包含的中间节点集合,\(s< 2^{mn}\le 2048\)。
\(i\) 表示包含的叶子节点个树,因为叶子节点都是一样的,所以这样可以优化状压。
值表示是否存在这样的森林,如果存在 \(=1\),否则 \(=0\)。
考虑怎么转移:
一棵森林(子树)和另一棵森林(子树)合并成新的森林。
一棵森林上面加一个 \(a=\) 森林大小 \(+1\) 的节点成为一棵子树(怎么求一棵森林的大小?其实就是 \({\rm popcount}(s)+i\) 啦)。
然后就剩初始化的问题了,因为 \(i\) 这维就像一个背包,而且因为 \(s\) 这一维保证不会有重点,所以可以在 dp
中用无限背包的方式,这样就只需要初始化 \(f_{0,0,1}=1\) 了。
时间复杂度 \(\Theta(ln^2 3^{mn})\),细节看代码。
代码
#include <bits/stdc++.h>
using namespace std;
//Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair((a),(b))
#define x first
#define y second
#define bg begin()
#define ed end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
#define R(i,a,b) for(int i=(a),i##E=(b);i<i##E;i++)
#define L(i,a,b) for(int i=(b)-1,i##E=(a)-1;i>i##E;i--)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
//Data
const int N=24,mN=11;
int n,sn,ln,mn,a[N],b[1<<mN];
int f[2][1<<mN][N+1]; // 森林还是子树,中间节点集,叶子节点数
bool get(int s,int i){ // 返回 f[1][s][i] 的值
for(int su=s;su;su=s&(su-1))if(!(su&(s^su)))R(j,0,i+1)
if((f[0][su][j]||f[1][su][j])&&(f[0][s^su][i-j]||f[1][s^su][i-j])) return true;
R(j,0,i+1)if((f[0][0][j]||f[1][0][j])&&(f[0][s][i-j]||f[1][s][i-j])) return true; // 因为 su!=0,补上循环中缺少的 su=0
return false;
}
//Main
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n; R(i,0,n) cin>>a[i]; sort(a,a+n,greater<int>());
R(i,0,n)if(a[i]>1) mn++; ln=n-mn,sn=1<<mn,sort(a,a+mn);
if(mn*2>=n) cout<<"NO\n",exit(0);
R(i,1,sn) b[i]=b[i>>1]+(i&1);
f[0][0][1]=true;
R(s,0,sn)R(i,0,ln+1)if(get(s,i)){
f[1][s][i]=true;
R(t,0,mn)if(!(s&(1<<t))&&a[t]==b[s]+i+1) // 加新的 a= 森林大小+1 的节点形成子树
f[0][s^(1<<t)][i]=true;
}
if(f[0][sn-1][ln]) cout<<"YES\n";
else cout<<"NO\n";
return 0;
}
祝大家学习愉快!
题解-CF429C Guess the Tree的更多相关文章
- 题解:CF593D Happy Tree Party
题解:CF593D Happy Tree Party Description Bogdan has a birthday today and mom gave him a tree consistin ...
- 题解-AtCoder Code-Festival2017 Final-J Tree MST
Problem \(\mathrm{Code~Festival~2017~Final~J}\) 题意概要:一棵 \(n\) 个节点有点权边权的树.构建一张完全图,对于任意一对点 \((x,y)\),连 ...
- PAT甲题题解-1110. Complete Binary Tree (25)-(判断是否为完全二叉树)
题意:判断一个节点为n的二叉树是否为完全二叉树.Yes输出完全二叉树的最后一个节点,No输出根节点. 建树,然后分别将该树与节点树为n的二叉树相比较,统计对应的节点个数,如果为n,则为完全二叉树,否则 ...
- [LeetCode 题解]: Validate Binary Search Tree
Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...
- leetcode题解:Construct Binary Tree from Inorder and Postorder Traversal(根据中序和后序遍历构造二叉树)
题目: Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume ...
- 题解 CF383C 【Propagating tree】
这道题明明没有省选难度啊,为什么就成紫题了QAQ 另:在CF上A了但是洛谷Remote Judge玄学爆零. 思路是DFS序+线段树. 首先这道题直观上可以对于每一次修改用DFS暴力O(n),然后对于 ...
- 题解 [CF916E] Jamie and Tree
题面 解析 这题考试时刚了四个小时. 结果还是爆零了 主要就是因为\(lca\)找伪了. 我们先考虑没有操作1,那就是裸的线段树. 在换了根以后,主要就是\(lca\)不好找(分类讨论伪了). 我们将 ...
- 题解 【HEOI2016】tree树
题面 解析 其实这题可以考虑离线做法,用并查集解决. 因为仔细想,添加标记并不方便, 但如果用并查集记录下祖先, 再一一删除,就会方便很多. 先把每次操作记录下来, 同时记录下每个点被标记的次数(因为 ...
- 题解-hzy loves segment tree I
Problem 题目概要:给定一棵 \(n\) 个节点的树,点有点权,进行 \(m\) 次路径取\(\max\)的操作,最后统一输出点权 \(n\leq 10^5,m\leq 5\times 10^6 ...
随机推荐
- mysql一些好的问题
一."N叉树"的N值在MySQL中是可以被人工调整吗? 1, 通过改变key值来调整N叉树中非叶子节点存放的是索引信息,索引包含Key和Point指针.Point指针固定为6个字节 ...
- TextView之富文本
项目中使用富文本比较常见了,一行显示多种样式颜色的文本,使用 ClickableSpan 富文本实现在同一个 TextView 中的文本的颜色.大小.背景色等属性的多样化和个性化. 我们也可以使用Ht ...
- 六:Redis配制文件
1.它在哪儿 1.1 安装包解压开里面就会有redis.conf 1.2 我们在修改一定要拷贝一份,修改拷贝的那一份 2.Units单位 2.1 对于单位来说配制开头定义了,1k和1kb是不一样的,同 ...
- 洛谷 P2101 命运石之门的选择 (分治)
P2101 命运石之门的选择 (分治) 介绍 El Psy Congroo 题目链接 没错,作为石头门厨,怎么能不做石头门的题呢?(在搜石头门的时 候搜到了本题) 本题作为一道分治基础练习题还是不错的 ...
- OMV openmediavault NAS系统命令显示颜色
闲鱼65f元买的我家云刷了OMV系统. 但ls命令查看文件不显示颜色. cd /etc/进入配置文件目录查看并没有bashrc文件,但有个bash.bashrc 在 bash.bashrc后面加入以下 ...
- Linux Shell操作 执行C代码显示当前路径
在unix系统下一切皆文件,文件夹是文件的一种.设备也会对应到相应的文件类型. 基础知识: . 代表当前路径 ..代表上级目录(父目录) / 在路径的最前边的时候代表树根.在路径中间的时候只不过是路径 ...
- C#设计模式-外观模式(Facade Pattern)
引言 在软件测试中,一般都是在功能测试稳定的情况下再进行UI自动化测试.或者进行性能测试.如果一个一个进行太麻烦,此时可以使用对外提供一个简单接口,通过这个接口可以访问内部一群接口.例如进行UI自动化 ...
- java后端开发三年!你还不了解Spring 依赖注入,凭什么给你涨薪
前言 前两天和一个同学吃饭的时候同学跟我说了一件事,说他公司有个做了两年的人向他提出要涨薪资,他就顺口问了一个问题关于spring依赖注入的,那个要求涨薪的同学居然被问懵了...事后回家想了想这一块确 ...
- MAC系统网页链接如何下载
Folx 5 是一款简单易用.功能强大的Mac OS系统的下载管理器.Folx界面简洁,下载管理方便,支持网页链接下载.BT下载和YouTube下载,而且还可以设置计划任务.搜索BT种子以及添加Tra ...
- 带你了解Boom 3D的Mac版音效模式
音乐是很好的情绪抒发途径,因为音乐蕴含了很多信息,包含了很多情感,所以我们聆听不同种类的音乐的时候会产生不同的心理感受.这就是音乐的魅力,可以让人产生共鸣引发无数的思绪.为了能够更好的体会感受音乐可以 ...