题目描述

给出一个有 $2^n$ 个叶子节点的完全二叉树。每个叶子节点可以选择黑白两种颜色。

对于每个非叶子节点左子树中的叶子节点 $i$ 和右子树中的叶子节点 $j$ :
如果 $i$ 和 $j$ 的颜色都为当前节点子树中颜色较多(相等视为白色)的那个,则不需要付出代价;
都为较小的那个则需要付 $2f[i][j]$ 的代价;
否则需要付 $f[i][j]$ 。

求最小代价。

输入

输入文件中第一行有一个正整数N。 第二行有2N个整数,依次表示1号,2号,…,2N号用户注册时的付费方式,每一个数字若为0,则表示对应用户的初始付费方式为A,否则该数字为1,表示付费方式为B。 第三行有2N个整数,表示每一个用户修改付费方式需要支付的费用,依次为C1, C2, …,CM 。( M=2N ) 以下2N-1行描述给定的两两用户之间的流量表F,总第(i + 3)行第j列的整数为Fi, j+i 。(1≤i<2N,1≤j≤2N ? i) 所有变量的含义可以参见题目描述。N≤10,0≤Fi, j≤500,0≤Ci≤500 000

输出

你的程序只需要向输出文件输出一个整数,表示NS中学支付给网络公司的最小总费用。(单位:元)

样例输入

2
1 0 1 0
2 2 10 9
10 1 2
2 1
3

样例输出

8


题解

暴力+树形背包dp

先Orz一发CQzhangyu

首先观察付出代价的方式,可以改看作为:对于 $i$ ,选了颜色较少的那个则需要付出 $f[i][j]$ 的代价。这样我们就把两个点之间的代价转化为了单个点的代价。

然后由于这么多状态难以统计,因此需要提前计算代价。

设 $f[i][j]$ 表示点 $i$ 为根的子树内有 $j$ 个叶子节点选了黑色的最小总代价。那么这是一个树形背包问题,递归左右子树后跑背包合并即可。

然而这里有一个非常大的问题:代价的类型是与颜色较少还是较多有关的。

CQzhangyu给出的解法是:暴力枚举这两种情况,分别留下有用部分。由于是完全二叉树,因此有递归式:$T(1)=\log n,T(n)=4T(\frac n2)+O(n^2)$ ,不考虑 $T(1)$ 时根据主定理解得 $T(n)=O(n^2\log n)$ ,单独考虑 $T(1)$ ,1被考虑了 $n^2$ 次,因此也是 $O(n^2\log n)$ 。

因此直接暴力的复杂度是对的。

时间复杂度 $O(2^{2n}·n)$ 。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1030
#define ls x << 1
#define rs x << 1 | 1
using namespace std;
typedef long long ll;
int n , m , a[N] , t[N];
ll c[N] , w[N][N] , v[N][N] , f[N << 1][N];
void init(int x , int d)
{
if(!d) return;
int i , j;
init(ls , d - 1) , init(rs , d - 1);
for(i = x << d ; i < ((x << 1) + 1) << (d - 1) ; i ++ )
for(j = ((x << 1) + 1) << (d - 1) ; j < (x + 1) << d ; j ++ )
v[i - m][x] += w[i - m][j - m] , v[j - m][x] += w[i - m][j - m];
}
void dfs(int x , int d)
{
int i , j;
if(!d)
{
f[x][a[x - m]] = 0;
f[x][a[x - m] ^ 1] = c[x - m];
for(i = x >> 1 ; i ; i >>= 1) f[x][t[i]] += v[x - m][i];
return;
}
memset(f[x] , 0x3f , sizeof(ll) * ((1 << d) + 1));
t[x] = 1 , dfs(ls , d - 1) , dfs(rs , d - 1);
for(i = 0 ; i <= 1 << (d - 1) ; i ++ )
for(j = 0 ; j <= (1 << (d - 1)) - i ; j ++ )
f[x][i + j] = min(f[x][i + j] , f[ls][i] + f[rs][j]);
t[x] = 0 , dfs(ls , d - 1) , dfs(rs , d - 1);
for(i = 1 ; i <= 1 << (d - 1) ; i ++ )
for(j = (1 << (d - 1)) - i + 1 ; j <= 1 << (d - 1) ; j ++ )
f[x][i + j] = min(f[x][i + j] , f[ls][i] + f[rs][j]);
}
int main()
{
int i , j;
ll ans = 1ll << 62;
scanf("%d" , &n) , m = 1 << n;
for(i = 0 ; i < m ; i ++ ) scanf("%d" , &a[i]);
for(i = 0 ; i < m ; i ++ ) scanf("%lld" , &c[i]);
for(i = 0 ; i < m ; i ++ )
for(j = i + 1 ; j < m ; j ++ )
scanf("%lld" , &w[i][j]);
init(1 , n);
dfs(1 , n);
for(i = 0 ; i <= m ; i ++ ) ans = min(ans , f[1][i]);
printf("%lld\n" , ans);
return 0;
}

【bzoj1495】[NOI2006]网络收费 暴力+树形背包dp的更多相关文章

  1. BZOJ1495 [NOI2006]网络收费 【树形dp + 状压dp】

    题目链接 BZOJ1495 题解 观察表格,实际上就是分\(A\)多和\(B\)两种情况,分别对应每个点选\(A\)权值或者\(B\)权值,所以成对的权值可以分到每个点上 所以每个非叶节点实际对应一个 ...

  2. BZOJ_1495_[NOI2006]网络收费_树形DP

    BZOJ_1495_[NOI2006]网络收费_树形DP Description 网络已经成为当今世界不可或缺的一部分.每天都有数以亿计的人使用网络进行学习.科研.娱乐等活动.然而, 不可忽视的一点就 ...

  3. 【bzoj4007】[JLOI2015]战争调度 暴力+树形背包dp

    题目描述 给你一棵 $n$ 层的完全二叉树,每个节点可以染黑白两种颜色.对于每个叶子节点及其某个祖先节点,如果它们均为黑色则有一个贡献值,如果均为白色则有另一个贡献值.要求黑色的叶子节点数目不超过 $ ...

  4. 【BZOJ1495】[NOI2006]网络收费 暴力+DP

    [BZOJ1495][NOI2006]网络收费 Description 网络已经成为当今世界不可或缺的一部分.每天都有数以亿计的人使用网络进行学习.科研.娱乐等活动.然而,不可忽视的一点就是网络本身有 ...

  5. bzoj1495 [NOI2006]网络收费 复杂度分析+树上背包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1495 题解 通过观察可以发现,对于一个 \(lca\),如果 \(nA \leq nB\),那 ...

  6. BZOJ1495 [NOI2006]网络收费

    题意 传送门 MY市NS中学,大概是绵阳市南山中学. 分析 参照Maxwei_wzj的题解. 因为成对的贡献比较难做,我们尝试把贡献算到每一个叶子节点上.我们发现按照题目中的收费方式,它等价于对于每棵 ...

  7. 洛谷 P4297 [NOI2006]网络收费

    P4297 [NOI2006]网络收费 题目背景 noi2006 day1t1 题目描述 网络已经成为当今世界不可或缺的一部分.每天都有数以亿计的人使用网络进行学习.科研.娱乐等活动.然而,不可忽视的 ...

  8. 【简】题解 P4297 [NOI2006]网络收费

    传送门:P4297 [NOI2006]网络收费 题目大意: 给定一棵满二叉树,每个叶节点有一个状态(0,1),任选两个叶节点,如果这两个叶节点状态相同但他们的LCA所管辖的子树中的与他们状态相同的叶节 ...

  9. 并不对劲的[noi2006]网络收费

    题目略长,就从大视野上复制了. 听上去好像费用流,然而…… ***************************表示略长的题目的分界线************************ 1495: [ ...

随机推荐

  1. Python中的对象引用、浅拷贝与深拷贝

    最近项目中遇到一个Python浅拷贝机制引起的bug,由于对于Python中对象引用.赋值.浅拷贝/深拷贝机制没有足够的认识,导致调试了很久才发现问题,这里简单记录一下相关概念. 在Python的设计 ...

  2. day 2 异常传递 ,抛出

    1.异常的传递 def test1(): print("---test1--") print(num) print('---test1 over---') def test2(): ...

  3. bootstrap 4 panels已被card替换

    https://www.zhihu.com/question/34838389?sort=created 解决问题的思路不对,不应该搜不到就各种着急,应该理清思路, 既然 bootstrap4没有了3 ...

  4. 【RAC搭建报错】libcap.so.1:cannot open shared object file

    原文参考:http://blog.csdn.net/siyanyanyanyai/article/details/45306595 http://orax.blog.sohu.com/26207226 ...

  5. Redis主从复制(Master/Slave) 与哨兵模式

    Redis主从复制是什么? 行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主 Redis主从复制 ...

  6. Http协议工作特点和工作原理笔记

    工作特点: (1)B/S结构(Browser/Server,浏览器/服务器模式) (2)无状态 (3)简单快速.可使用超文本传输协议.灵活运行传输各种类型 工作原理: 客户端发送请求浏览器 -> ...

  7. Linux 安装Zookeeper<单机版>(使用Mac远程访问)

    阅读本文需要先阅读安装Zookeeper<准备> 新建目录 mkdir /usr/local/zookeeper 解压 cd zookeeper压缩包所在目录 tar -xvf zooke ...

  8. PHP自定义生成二维码跳转地址

      比较简单的一款PHP自定义生成二维码跳转地址,手机端微信扫码,自动跳转到定义好的链接.支持自定义生成二维码尺寸.间距等.    鼠标悬浮显示二维码弹出层,离开后消失.js实现,代码如下: $(fu ...

  9. openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 二

    openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一 openstack-r版(rocky)搭建基于centos7.4 的openstac ...

  10. 算法笔记(c++)--回文

    算法笔记(c++)--回文 #include<iostream> #include<algorithm> #include<vector> using namesp ...