uvalive 6669 hidden tree(好壮压dp)
来源:互联网 发布:淘宝差评能追评吗 编辑:程序博客网 时间:2024/06/05 16:43
题目见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;}
1 0
- uvalive 6669 hidden tree(好壮压dp)
- UVALive 6669 Hidden Tree DP
- UVALive 6669 Hidden Tree(状压DP)
- UVALive 4847 Binary Search Tree【树型dp】
- UVALive 5861 Hidden Terminal Problem 解题报告
- UVALive 2755 Hidden Password(字符串最小表示)
- UVALive 6850 Hidden Plus Signs(dfs)
- UVALive 2755 Hidden Password (最小表示法)
- UVALive 4725 Airport 【DP】
- UVAlive 5875 DP
- DP->UVALive 4764
- uvalive 3029(dp)
- uvalive 3983(dp)
- UVALive - 3983 Robotruck DP
- UVALive 6801 Sequence (DP)
- uvalive 3942(dp + trie)
- uvalive 4256(dp)
- 【DP】UVALive 6400 Matryoshka
- Spring中常用的一些注解
- FZU 1686 神龙的难题 重复覆盖
- CodeVs 1017 乘积最大
- stl_hash_set.h
- stl_hash_map.h
- uvalive 6669 hidden tree(好壮压dp)
- stl_algobase.h
- hdu 3488 Tour(二分图的最优匹配)
- c语言中的逻辑运算符都是短路运算符
- BW数据源深入研究【转自WKingChen的博客】
- VS2013 “WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping
- stl_relops.h
- Spring mvc 框架总体搭建过程异常总结
- 动态树之详解