bzoj 4007
非常好的树形dp
首先,有个很显然的状态:记状态f[i][j]表示以i为根节点的子树中选了j个叶节点作战,那么很显然有转移:f[i][j1+j2]=f[i<<1][j1]+f[i<<1|1][j2]
所以我们只需爆搜一发状态,然后每次更新即可
但是有个问题:当我们搜到最底层的叶节点时,由于他的贡献与祖先节点有关,所以无法直接更新
但是我们发现,n的数据范围非常小,而且一个叶节点产生的贡献只会与他上面一条链的状态有关,所以我们在dfs的时候暴力记录每个点的状态,然后搜到叶节点的时候直接更新即可。
注意一下二叉树的性质:如果设根节点的高度为h,那么这个二叉树会有(1<<(h-1))+1个节点,这里不要算错了
剩下就是更新了
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define rt1 rt<<1
#define rt2 (rt<<1)|1
using namespace std;
int v1[][],v2[][],f[][];
int n,m;
bool col[];
void dfs(int rt,int h)
{
for(int i=;i<=((<<h));i++)
{
f[rt][i]=;
}
if(!h)
{
for(int i=;i<=n;i++)
{
if(!col[i])
{
f[rt][]+=v2[rt][i];
}else
{
f[rt][]+=v1[rt][i];
}
}
return;
}
col[h]=;
dfs(rt1,h-);
dfs(rt2,h-);
for(int i=;i<=(<<(h-));i++)
{
for(int j=;j<=(<<(h-));j++)
{
f[rt][i+j]=max(f[rt][i+j],f[rt1][i]+f[rt2][j]);
}
}
col[h]=;
dfs(rt1,h-);
dfs(rt2,h-);
for(int i=;i<=(<<(h-));i++)
{
for(int j=;j<=(<<(h-));j++)
{
f[rt][i+j]=max(f[rt][i+j],f[rt1][i]+f[rt2][j]);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<(<<(n-));i++)
{
for(int j=;j<n;j++)
{
scanf("%d",&v1[i+(<<(n-))][j]);
}
}
for(int i=;i<(<<((n-)));i++)
{
for(int j=;j<n;j++)
{
scanf("%d",&v2[i+(<<(n-))][j]);
}
}
dfs(,n-);
int ans=;
for(int i=;i<=m;i++)
{
ans=max(ans,f[][i]);
}
printf("%d\n",ans);
return ;
}
bzoj 4007的更多相关文章
- 【BZOJ 4007】[JLOI2015]战争调度 DP+搜索+状压
又是一道思路清新的小清晰. 观察题目,如果我们确定了平民或者贵族的任意一方,我们便可以贪心的求出另一方,至此20分:我们发现层数十分小,那么我们就也是状压层数,用lca转移,线性dp,至此50分(好像 ...
- bzoj 4007 树形dp
题目大意 脸哥最近来到了一个神奇的王国,王国里的公民每个公民有两个下属或者没有下属,这种关系刚好组成一个 n 层的完全二叉树.公民 i 的下属是 2 * i 和 2 * i +1.最下层的公民即叶子节 ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
随机推荐
- Flask恋爱的一瞬间
python的三大框架:Flask:轻量级框架 Django:重量级框架 Tornado:性能最好,异步框架 Flask初学 #导包 from flask import Flask #建立flask对 ...
- Django学习手册 - reverse()反转URL
前端: <h1>测试</h1> <a href="/ce_test/?id=1">1按键</a> <a href=" ...
- requirements.txt文件教程
方法有2种,命令都是一样,只是执行地方不一样 此方法主要用于迁移新环境使用,为防止代码出现问题,最好使用原装库,所以就有了迁移代码和库的操作 第一种:在pycharm中,左下角有个双重正方形,点击里面 ...
- 【上载虚拟机】XX是一个Workstations 12.X虚拟机,不受XX支持。请选择其他主机或将虚拟机的硬件版本更改为以下选项之一。
背景 由于搭建集群时,要使用Ubuntu系统,还有一点就是咱们使用的Ubuntu系统是定制的,但是它是一个虚拟机,需要通过VMware Workstations这款软件,把咱们定制好的Ubuntu系统 ...
- Python 脚本碎片
基本输入输出 用户名/密码 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # Liu Lei import getpass username = inpu ...
- 设计模式C++学习笔记之十二(Command命令模式)
命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作.应该是一个比较简单的模式了. 12.1.解释 main(),客户 CIn ...
- unity制作背景
- 移动硬盘和u盘的区别
移动硬盘和U盘都属于便携性存储器,用于计算机之间的数据交换.但移动硬盘和U盘的区别还是非常大的,包括内部构造.容量以及整体外观上. 移动硬盘又分为机械移动硬盘和固态移动硬盘两种,主要区别在于内置的存储 ...
- centos6下安装php7的memcached扩展
安装php7的memcached扩展 .编译安装libmemcached- wget https://launchpadlibrarian.net/165454254/libmemcached-1.0 ...
- Centos7环境下etcd集群的搭建
Centos7环境下etcd集群的搭建 一.简介 "A highly-available key value store for shared configuration and servi ...