题目见

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. DCDCBigBig's first blog @cnblogs~

    其实初二末的时候我就在CSDN上开了博客(主要是为了存模板),但是无奈CSDN的页面真的太辣眼睛了…… 然后我就加入博客园欢快的大家庭啦!!!顺便膜拜巨佬学长%%%(我是蒟蒻不要喷我) 页面设置感谢x ...

  2. C语言静态库与动态库(Windows下测试)

    转载于:https://zhidao.baidu.com/question/1946953913764139388.html,原文为Linux上测试,本文为在Windows上编译测试 我们通常把一些公 ...

  3. python编写登录与注册

    #编写简单的注册与登陆模块 #使用死循环来检测 while True: #如果条件为真,则一直循环 sum=3 #定义密码输入的次数 username = input("请输入用户名:&qu ...

  4. 第五周-磁盘分区GPT、shell脚本练习、lvm详解

    1. 描述GPT是什么,应该怎么使用 Linux中磁盘分区分为MBR和GPT. MBR全称为Master Boot Record,为主引导记录,是传统的分区机制,应用于绝大多数使用的BIOS的PC设备 ...

  5. pip 出错

    pip 升级到10以上出错 ImportError: cannot import name 'main' 解决方法一: 降低pip的版本号 python -m pip install pip==9.0 ...

  6. Ubuntu16.04 lnmp 环境搭建

    Ubuntu16.04 lnmp 环境搭建 nginx 安装 sudo apt-add-repository ppa:nginx/stablesudo apt-add-repository ppa:o ...

  7. python+selenium进行简单验证码获取

    # _*_ coding:utf-8 _*_from PIL import Imagefrom selenium import webdriverimport pytesseractimport ti ...

  8. Python实现机器人语音聊天

    一.前言说明 1.功能简述 登录后进入聊天界面,如果服务器都在同一个地址,则都进入同一个房间 进入/离开/发消息同一房间用户都可以看到,输入“tuling”或“chatbot”可以切换为和Tuling ...

  9. MAC中Parallels Desktop windows忘记密码的解决办法

    由于工作或是生活,在国内的环境下我们总有些时候要用到Windows才能完成某些任务,对于不经常使用Windows的用户,相信在虚拟机上安装一个Windows是不错的选择.小编就使用了Paralles ...

  10. 将Spring Boot应用程序迁移到Java9:兼容性

    将 Spring Boot 应用程序迁移到 Java 9:兼容性 随着 Java 9 的到来,关于如何迁移应用程序以使用模块系统有很多的讨论.遗憾的是,大多数文章的焦点都集中于简单的 Hello Wo ...