题目描述

给出一个有 $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. html 第一行不缩进,第二行缩进,文字对齐

    <p style="text-indent: -7rem;margin-left: 7rem;"> <img src="images/记录要求.png& ...

  2. swift3.0通过响应链获取当前试图的控制器

    func parentViewController() -> UIViewController? { let n = next while n != nil { let controller = ...

  3. (treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...

  4. QQ在线交谈一句代码搞定

    现在有很多网页都有QQ在线咨询,还有什么QQ客服什么的,看着很高大上的一个功能,其实要实现很简单,只需要一句代码就搞定. 还是按以前的套路,先看效果图,再晒源代码 点击图标 再点击 就可以聊天了 再来 ...

  5. C#之#if #endif的简单用法

    有时候我们看到别人的代码中有#if #endif,其实这是通过不同版本来选择运行哪段代码,和咱们的if,else是一样的.下面看下简单的用法 #if DEBUG txt_display.Text = ...

  6. Jmeter直连postgresql数据库进行压测

    关于Jmeter直连数据库进行压测,网上有好多教程了,pg数据库的相对少一些,今天自己测试了下,还是挺简单的,有个别需要注意的地方.相较于Loadrunner这么全面庞大的压测工具,Jmeter在数据 ...

  7. pyquery详细用法

    python爬虫之PyQuery的基本使用   PyQuery库也是一个非常强大又灵活的网页解析库,如果你有前端开发经验的,都应该接触过jQuery,那么PyQuery就是你非常绝佳的选择,PyQue ...

  8. .net core 2.1.3可能引发Could not load file or assembly XXXXX的错误

    参考文档: https://github.com/aspnet/Home/issues/3503 写在前面 感觉自己现在干的活离开发越来越远了啊,不过也很好,每天能学到不少东西,中文的,英文的,永远也 ...

  9. Linux内核学习笔记(1)-- 进程管理概述

    一.进程与线程 进程是处于执行期的程序,但是并不仅仅局限于一段可执行程序代码.通常,进程还要包含其他资源,像打开的文件,挂起的信号,内核内部数据,处理器状态,一个或多个具有内存映射的内存地址空间及一个 ...

  10. 【C#】人脸识别 视频数据转图片数据

    使用虹软人脸识别的开发过程中遇到了转换的问题 因为不会用C#直接打开摄像头,就只能用第三方dll.一开始用Aforge,后来发现有个问题,关闭摄像头老是陷入等待,所以抛弃了.前一阵子开始用封装了Ope ...