题目见

option=com_onlinejudge&Itemid=8&page=show_problem&problem=4681">here

题意:给一个序列arr[],你从中选择一些子序列,将子序列的值从左往右依次放到某棵二叉树的叶子节点上,使得除了叶子,全部节点左右子树权和相等。子树的权和 = 子树叶子的权和。

假设存在这样一棵二叉树,选择的子序列就是合法的。问,最长的合法子序列是多少。

思路:

枚举二叉树可能的叶子的最小权(入手点)。显然,能和此数一起组成二叉树的数,要么和这个数相等。要么是这个数的2^k倍。把满足这样的关系的数。认做一个集合,显然集合外的数,不能和集合内的数组成二叉树。那么,我们仅仅须要一个一个得求出全部集合的最长子序列就可以。

把集合内的所有数所有除以最小权。剩下的数为1,2,4,8,16,32,64.....这样的2^k的数。如果你从左到右。第一个填的数为16,第二个填的数一定不会比16大,不然那个16无法合并。如果填的就是16,那就合成为32。当然,填小于16的数也是行的。

那么,对于2^k的数。每一个数,在合并过程中一定仅仅有两种状态。有1个,或者没有。

那么我们似乎就能够用状态压缩就可。

具体见代码:

#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1010;
typedef long long ll;
bool base[maxn*505],vis[505],iss[maxn];
int arr[maxn],dp[maxn*505],brr[maxn],sum[maxn];
int solve(int x,int n)
{
int i,j,lim,tp,ct=0,ans=0;
for(i=1;i<=n;i++)
if(arr[i]%x==0&&base[arr[i]/x])
brr[++ct]=arr[i]/x;
for(i=1;i<=ct;i++)
sum[i]=sum[i-1]+brr[i];
memset(dp,0xcf,sizeof dp);
dp[0]=0;
for(i=1;i<=ct;i++)
{
lim=2*brr[i];
for(j=sum[i];j>=lim;j--)
{
tp=j-brr[i];
if(!(tp&(brr[i]-1)))
dp[j]=max(dp[j],dp[tp]+1);
}
dp[brr[i]]=max(dp[brr[i]],1);
}
for(i=1;i<=sum[ct];i++)
if(base[i])
ans=max(ans,dp[i]);
return ans;
}
int main()
{
int n,i,j,lim,ans; lim=500*maxn;
for(i=1;i<lim;i<<=1)
base[i]=true;
while(scanf("%d",&n),n)
{
for(i=1;i<=n;i++)
scanf("%d",&arr[i]);
memset(vis,0,sizeof vis);
for(i=1;i<=n;i++)
{
iss[i]=true;//是否叶子结点最小权值
if(vis[arr[i]])
{
iss[i]=false;
continue;
}
vis[arr[i]]=true;
for(j=1;j<=n;j++)
{
if(j==i)
continue;
if(arr[i]!=arr[j]&&arr[i]%arr[j]==0&&base[arr[i]/arr[j]])
{
iss[i]=false;
break;
}
}
}
ans=0;
for(i=1;i<=n;i++)
if(iss[i])
ans=max(ans,solve(arr[i],n));
printf("%d\n",ans);
}
return 0;
}

uvalive 6669 hidden tree(好壮压dp)的更多相关文章

  1. [Usaco2006 Nov]Corn Fields牧场的安排 壮压DP

    看到第一眼就发觉是壮压DP 然后就三进制枚举子集吧. 这题真是壮压入门好题... 对于dp[i][j] 表示第i行,j状态下前i行的分配方案数. 那么dp[i][j]肯定是从i-1行转过来的 那么由于 ...

  2. POJ 2686 Traveling by Stagecoach 壮压DP

    大意是有一个人从某个城市要到另一个城市(点数<=30) 然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票. 花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间. 问最后这个人花费 ...

  3. UVALive - 6912 Prime Switch (状压DP)

    题目链接:传送门 [题意]有n个灯,m个开关,灯的编号从1~n,每个开关上有一个质数,这个开关同时控制编号为这个质数的倍数的灯,问最多有多少灯打开. [分析]发现小于根号1000的质数有10个左右,然 ...

  4. hdu 4284 Travel(壮压DP&TSP&floyd)

    Travel Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  5. hdu 3006 The Number of set(思维+壮压DP)

    The Number of set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  6. poj1699 KMP+壮压DP

    Best Sequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6338   Accepted: 2461 Des ...

  7. 状压DP uvalive 6560

    // 状压DP uvalive 6560 // 题意:相邻格子之间可以合并,合并后的格子的值是之前两个格子的乘积,没有合并的为0,求最大价值 // 思路: // dp[i][j]:第i行j状态下的值 ...

  8. 【思维题 状压dp】APC001F - XOR Tree

    可能算是道中规中矩的套路题吧…… Time limit : 2sec / Memory limit : 256MB Problem Statement You are given a tree wit ...

  9. 『Tree nesting 树形状压dp 最小表示法』

    Tree nesting (CF762F) Description 有两个树 S.T,问 S 中有多少个互不相同的连通子图与 T 同构.由于答案 可能会很大,请输出答案模 1000000007 后的值 ...

随机推荐

  1. 数据库应用_innobackupex备份与恢复

    1.Percona软件介绍; 2.innobackupex的备份与恢复 一, Percona软件 在学习percona软件之前,我们看一下物理备份和mysqldump备份有哪些缺陷. 物理备份的缺点: ...

  2. 人工智能,你到底是天使or魔鬼?

    人工智能的概念早在60多年前就被提出,但又一度沉寂.随着谷歌人工智能程序AlphaGo(阿尔法狗)战胜围棋世界冠军李世石,再次为世人瞩目.然而,与无限风光一起相伴而来的,还有关于人工智能的种种争议! ...

  3. 手把手教你如何新建scrapy爬虫框架的第一个项目(下)

    前几天小编带大家学会了如何在Scrapy框架下创建属于自己的第一个爬虫项目(上),今天我们进一步深入的了解Scrapy爬虫项目创建,这里以伯乐在线网站的所有文章页为例进行说明. 在我们创建好Scrap ...

  4. (2016北京集训十四)【xsy1556】股神小D - LCT

    题解: 题解居然是LCT……受教了 把所有区间按照端点排序,动态维护目前有重叠的区间,用LCT维护即可. 代码: #include<algorithm> #include<iostr ...

  5. AC自动机笔记

    AC自动机 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> ...

  6. java 获取config 配置文件

    static ResourceBundle PropertiesUtil = ResourceBundle.getBundle("config"); public static S ...

  7. [原创]Linux 下 redis 链接一次

    刚接触 Linux ,在 Linux 下安装 redis 链接redis 出现了以下问题  Could not connect to Redis at 127.0.0.1:6379: Connecti ...

  8. 【codeforces 255D】Mr. Bender and Square

    [题目链接]:http://codeforces.com/problemset/problem/255/D [题意] 给你一个n*n的方框; 给你一个方块;(以下说的方块都是单位方块) 每一秒钟,可以 ...

  9. 【转】C#正则表达式教程和示例

    [转]C#正则表达式教程和示例 有一段时间,正则表达式学习很火热很潮流,当时在CSDN一天就能看到好几个正则表达式的帖子,那段时间借助论坛以及Wrox Press出版的<C#字符串和正则表达式参 ...

  10. 生成apk文件遇到的编译问题error: format not a string literal and no format arguments

    编译错误时使用的android-ndk为r9的版本号.报下面错误: "Compile++ thumb : cocosdenshion_static <= SimpleAudioEngi ...