╰( ̄▽ ̄)╭

每个非叶子节点,其左右子树叶子节点的权值之和相等。我们称这种二叉树叫平衡二叉树。

我们将一棵平衡二叉树叶子节点的权值从左到右列出来,假如这个权值序列是另一个序列A的子序列,我们称这棵平衡二叉树“隐藏”在序列A当中。在本题中,我们称一个序列S2是另一个序列S1的子序列,当且仅当S2可以由S1中删除0个或多个元素,但不改变S1中剩余元素的相对位置获得。

你的任务是对给定的整数序列,寻找当中隐藏的具有最多叶子节点的平衡二叉树。

n<=1000,1<=ai<=500

(⊙ ▽ ⊙)

显而易见,我们先枚举一个base,并将所有满足a[i]=base∗2j的提取出来,

形成一个新的数列A。

那么原问题就转化为:对于一个只有2的幂数的数列A,求一个最多叶子结点的隐藏平衡二叉树。


容易想到,可以利用动态规划来做。

但问题在于如何写转移方程。


如果我们摒弃时间复杂度不谈,

设f[i][j]表示前i个数中,未合并的数之和为j,的最多合并次数。

显然f[i−1][j]+1⇒f[i][j+A[i]] (A[i]<=lowbit(j))

先明白lowbit()的意义。

lowbit(x)表示x的二进制中,只保留最低位的1及其后面的0,得到的数。

由于A[i]<=lowbit(j),理解为,A[i]可以暂时储存在j中,因此可以转移。

如果不满足A[i]<=lowbit(j),会导致不连续的合并,是不允许的。


f[i][j]的第一维可以滚动;

第二维,可以只枚举可以达到的和的最大值。

这样优化之后,可以勉强卡过。

( ̄~ ̄)

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#define ll long long
using namespace std;
const char* fin="tree.in";
const char* fout="tree.out";
const int inf=0x7fffffff;
const int maxn=1007,maxa=507,maxk=300000;
int n,i,j,k,ans=1;
int a[maxn];
int b[maxn],mi[maxn];
int f[maxk];
bool bz[maxa];
void solve(){
int i,j,k,l,MAX=0;
f[0]=0;
for (i=1;i<=b[0];i++){
for (j=MAX;j>=0;j--){
if (j==0 || (j&-j)>=b[i]){
k=j+b[i];
if (k>=maxk) continue;
f[k]=max(f[k],f[j]+1);
if ((k&-k)==k) ans=max(ans,f[k]);
MAX=max(MAX,k);
}
}
}
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%d",&a[i]);
//for (i=1,j=0;i<1<<maxk;i<<=1,j++) po[i]=j;
for (i=1;i<maxa;i++){
memset(bz,0,sizeof(bz));
memset(mi,0,sizeof(mi));
memset(f,128,sizeof(f));
for (j=i,k=0;j<maxa;j=j*2){
bz[j]=true;
mi[j]=++k;
}
b[0]=0;
for (j=1;j<=n;j++)
if (bz[a[j]]) b[++b[0]]=a[j]/i;
if (b[0]) solve();
}
printf("%d",ans);
return 0;
}

(⊙v⊙)

关键点:

1.把原数列中提取出一个新的数列。

通过枚举,来简化问题。

2.运用特殊的DP技巧

本题的具体操作是,发现了题目中的特殊性。

【JZOJ3601】【广州市选2014】Tree(tree)的更多相关文章

  1. 【2014广州市选day1】JZOJ2020年9月12日提高B组T4 字符串距离

    [2014广州市选day1]JZOJ2020年9月12日提高B组T4 字符串距离 题目 Description 给出两个由小写字母组成的字符串 X 和Y ,我们需要算出两个字符串的距离,定义如下: 1 ...

  2. 【2014广州市选day1】JZOJ2020年9月12日提高B组T3 消除游戏

    [2014广州市选day1]JZOJ2020年9月12日提高B组T3 消除游戏 题目 Description 相信大家玩过很多网络上的消除类型的游戏,一般来说就是在一个大拼图内找出相同的部分进行最大程 ...

  3. 【2014广州市选day1】JZOJ2020年9月12日提高B组T2 导弹拦截

    [2014广州市选day1]JZOJ2020年9月12日提高B组T2 导弹拦截 题目 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统 V1.0.但是这种导弹拦截系统有一个缺 ...

  4. BZOJ5465: [APIO 2018] 选圆圈(K-D Tree)

    题意 题目链接 Sol 下面是错误做法,正解请看这里 考虑直接用K-D tree模拟.. 刚开始想的是维护矩形最大最小值,以及子树中最大圆的位置,然后... 实际上最大圆的位置是不用维护的,直接把原序 ...

  5. 5.10 省选模拟赛 tree 树形dp 逆元

    LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...

  6. jzoj 6797. 【2014广州市选day2】hanoi

    Description 你对经典的hanoi塔问题一定已经很熟悉了.有三根柱子,n个大小不一的圆盘,要求大盘不能压在小盘上,初始时n个圆盘都在第一根柱子上,最少要多少步才能挪到最后一根柱子上? 现在我 ...

  7. jzoj 6798. 【2014广州市选day2】regions

    Description 在平面上堆叠着若干矩形,这些矩形的四边与平面X坐标轴或Y坐标轴平行.下图展示了其中一种情况,3个矩形的边将平面划分成8个区域: 下面展示了另一种稍稍复杂一些的情况: 你的任务是 ...

  8. 100. Same Tree(Tree)

    /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * Tre ...

  9. leetcode@ [236] Lowest Common Ancestor of a Binary Tree(Tree)

    https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/ Given a binary tree, find the ...

随机推荐

  1. TensorFlow实战Google深度学习框架-人工智能教程-自学人工智能的第二天-深度学习

    自学人工智能的第一天 "TensorFlow 是谷歌 2015 年开源的主流深度学习框架,目前已得到广泛应用.本书为 TensorFlow 入门参考书,旨在帮助读者以快速.有效的方式上手 T ...

  2. java实现从实体到SQL语句的转换

    使用过Hibernate,EF之类的ORM框架都知道一般的CRUD之类的简单操作,只要调用框架封装好了的方法,框架就自动生成相应的SQL语句了,参照实习公司给的代码,那个是C#版的,今天弄了一下jav ...

  3. python 创建txt每行写入

    txtPath=os.path.join(vocDir,"eval.txt") with open(txtPath,"w") as f: f.writeline ...

  4. 详解 equals() 方法和 hashCode() 方法

    创建实体类时,最好重写超类(Object)的hashCode()和equals()方法 equals()方法: 通过该实现可以看出,Object类的实现采用了区分度最高的算法,即只要两个对象不是同一个 ...

  5. HZOI20190823模拟31题解

    题面:https://www.cnblogs.com/Juve/articles/11425141.html math:仔细看看其实是个水题 #include<iostream> #inc ...

  6. 20191005 - New Beginning

    真·反思 Before 发现$T1$是约瑟夫,$T2$不清楚,$T3$是算法进阶上的$LCIS$ During得&失 做的不错的地方: 多少想了T1的优化(最后没打完). T3的暴力写得很快也 ...

  7. PAT甲级——A1062 Talent and Virtue

    About 900 years ago, a Chinese philosopher Sima Guang wrote a history book in which he talked about ...

  8. 023-linux(2)

    1. head 查看文件的前N行 -n ,表示查看前几行 head - test.txt 2. tail 查看文件的后N行 -n,表示查看文件的后几行 tail - test.txt -f(循环读取) ...

  9. python时间处理,datetime中的strftime/strptime

    python中datetime模块非常好用,提供了日期格式和字符串格式相互转化的函数strftime/strptime 1.由日期格式转化为字符串格式的函数为: datetime.datetime.s ...

  10. TZOJ 1503 Incredible Cows(折半搜索+二分)

    描述 Farmer John is well known for his great cows. Recently, the cows have decided to participate in t ...