uvalive 6669 hidden tree(好壮压dp)
题目见 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)的更多相关文章
- [Usaco2006 Nov]Corn Fields牧场的安排 壮压DP
看到第一眼就发觉是壮压DP 然后就三进制枚举子集吧. 这题真是壮压入门好题... 对于dp[i][j] 表示第i行,j状态下前i行的分配方案数. 那么dp[i][j]肯定是从i-1行转过来的 那么由于 ...
- POJ 2686 Traveling by Stagecoach 壮压DP
大意是有一个人从某个城市要到另一个城市(点数<=30) 然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票. 花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间. 问最后这个人花费 ...
- UVALive - 6912 Prime Switch (状压DP)
题目链接:传送门 [题意]有n个灯,m个开关,灯的编号从1~n,每个开关上有一个质数,这个开关同时控制编号为这个质数的倍数的灯,问最多有多少灯打开. [分析]发现小于根号1000的质数有10个左右,然 ...
- hdu 4284 Travel(壮压DP&TSP&floyd)
Travel Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- 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 ...
- poj1699 KMP+壮压DP
Best Sequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6338 Accepted: 2461 Des ...
- 状压DP uvalive 6560
// 状压DP uvalive 6560 // 题意:相邻格子之间可以合并,合并后的格子的值是之前两个格子的乘积,没有合并的为0,求最大价值 // 思路: // dp[i][j]:第i行j状态下的值 ...
- 【思维题 状压dp】APC001F - XOR Tree
可能算是道中规中矩的套路题吧…… Time limit : 2sec / Memory limit : 256MB Problem Statement You are given a tree wit ...
- 『Tree nesting 树形状压dp 最小表示法』
Tree nesting (CF762F) Description 有两个树 S.T,问 S 中有多少个互不相同的连通子图与 T 同构.由于答案 可能会很大,请输出答案模 1000000007 后的值 ...
随机推荐
- 路飞学城Python-Day10(practise)
作业:现要求你写一个简单的员工信息增删该查程序,需求如下:当然此表在文件存储时可以这样表示1,Alex Li,22,13651054608,IT,2013-04-012,Jack Wang,28,13 ...
- iOS面试总结(待完善)
闲的没事总结一下面试资料,先列个大纲,然后慢慢填充,一步步完善,反正也不急. 1.基本属性 2.KVC与KVO 3.代理与block 4.多线程:NSThread,GCD,NSOperation 5. ...
- 地图底图的类型——MapView,SceneView
MapView用于创建二维地图平面. 引用“esri/Map”,"esri/views/MapView" 具体做法并举例:var map = new Map({basemap:&q ...
- 微信小程序 上传图的功能
首先选择图片,然后循环,再就是在点击发布的时候循环图片地址赋值,包括删除命令 js代码: //选择图片 uploadImgAdd: function(e) { var imgs = this.data ...
- 【BZOJ 1207】[HNOI2004]打鼹鼠
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 时间是按顺序的. 所以就有单调性啦. 写个DP就好. 设f[i]表示打第i只鼹鼠,最多能打几只鼹鼠. 则如果i和j的距离不超过它们的 ...
- gps 地图
http://www.cnblogs.com/sylvanas2012/p/5342530.html http://blog.csdn.net/ma969070578/article/details/ ...
- JConsole远程监控Tomcat7
下面技术应用于最优质的水果的鲜果篮 一.设置服务端: 1.增加Listener到conf/server.xml <Listener className="org.apache.cata ...
- JavaWeb利用cookie记住账号
JavaWeb利用cookie记住账号. 首先,来看看界面什么样子. 记住账号最普遍的做法,就是在点击登录时,将账号保存到cookie中. 材料准备 <script src="${ct ...
- Hadoop2.6.0配置參数查看小工具
前言 使用Hadoop进行离线分析或者数据挖掘的project师,常常会须要对Hadoop集群或者mapreduce作业进行性能调优. 或许你知道通过浏览器訪问http://master:18088/ ...
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD
Build.VERSION.SDK_INT是系统的版本,Build.VERSION_CODES.GINGERBREAD是版本号. 到VERSION.SDK_INT不禁诧异,这是何物?! 看API的定义 ...