题意

给定一棵满二叉树,每个叶节点有一个状态0/10/10/1,对于每两个叶节点i,ji,ji,j,如果这两个叶节点状态相同但他们的LCALCALCA所管辖的子树中的与他们状态相同的叶节点个数较少(少于1/21/21/2),则会产生2fij2f_{ij}2fij​的代价,如果状态不同,则产生fijf_{ij}fij​的代价,如果状态相同且LCALCALCA管辖子树中与他们状态相同叶节点个数较多,则不产生代价,现在每个节点可以变更状态,但变更状态也有自己的代价,求最小总代价 。

题解

在满二叉树上暴力枚举这个点子树中是000多还是111多,然后递归下去DPDPDP合并。时间复杂度是O(2n⋅2n⋅n)O(2^n\cdot 2^n\cdot n)O(2n⋅2n⋅n)的。对于每一个叶子结点,到根的路径最长只有nnn,所有情况就是2n2^n2n,所以所有叶子节点加起来的时间复杂度是2n⋅2n2^n\cdot 2^n2n⋅2n,由于还要枚举这条路径上的点算代价,所以就再乘个nnn。

费用的计算方法就是:

对于点对(i,j)(i,j)(i,j)的贡献,如果LCALCALCA和iii异色,费用就加上一个fijf_{ij}fij​,如果LCALCALCA和jjj异色,就再加上一个fijf_{ij}fij​。可以发现这样算出来的答案恰好符合题意。LCALCALCA的颜色就表示子树下面111多还是000多,这个是暴力枚举的。

具体实现看代码。

CODE

dp[i][j]dp[i][j]dp[i][j]表示在iii的子树里选了jjj个111的最小费用。

#pragma GCC optimize (3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 2060;
const LL INF = 1ll<<40;
int f[MAXN][2], n, all, a[MAXN];
LL dp[MAXN][MAXN], cst[MAXN][12];
bool clr[12];
void dfs(int x, int dep) {
for(int i = 0; i <= all; ++i) dp[x][i] = INF;
if(dep == n) {
dp[x][0] = f[x-all][0];
dp[x][1] = f[x-all][1];
for(int i = 0; i < n; ++i) dp[x][clr[i]^1] += cst[x-all][i];
return;
}
int half = 1<<(n-dep-1);
clr[dep] = 0; dfs(x<<1, dep+1), dfs(x<<1|1, dep+1);
for(int i = 0; i <= half; ++i)
for(int j = 0; i+j <= half; ++j)
dp[x][i+j] = min(dp[x][i+j], dp[x<<1][i] + dp[x<<1|1][j]); clr[dep] = 1; dfs(x<<1, dep+1), dfs(x<<1|1, dep+1);
for(int i = 0; i <= half; ++i)
for(int j = half+1-i; j <= half; ++j)
dp[x][i+j] = min(dp[x][i+j], dp[x<<1][i] + dp[x<<1|1][j]);
}
int lca_dep(int u, int v) {
for(int i = n-1; i >= 0; --i) if((u>>i) != (v>>i)) return n-i-1;
}
int main () {
scanf("%d", &n); all = 1<<n;
for(int i = 0; i < all; ++i) scanf("%d", &a[i]);
for(int i = 0; i < all; ++i) f[i][a[i]] = 0, scanf("%d", &f[i][a[i]^1]);
for(int i = 0; i < all; ++i)
for(int j = i+1; j < all; ++j) {
int k = lca_dep(i, j), v; scanf("%d", &v);
cst[i][k] += v, cst[j][k] += v;
}
dfs(1, 0);
printf("%lld\n", *min_element(dp[1], dp[1] + all + 1));
}

BZOJ 1495 [NOI2006]网络收费(暴力DP)的更多相关文章

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

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

  2. 5.21 省选模拟赛 luogu P4297 [NOI2006]网络收费 树形dp

    LINK:网络收费 还是自己没脑子. 早上思考的时候 发现树形dp不可做 然后放弃治疗了. 没有合理的转换问题的模型是我整个人最大的败笔. 暴力也值得一提 爆搜之后可以写成FFT的形式的计算贡献的方法 ...

  3. 【bzoj1495】[NOI2006]网络收费 暴力+树形背包dp

    题目描述 给出一个有 $2^n$ 个叶子节点的完全二叉树.每个叶子节点可以选择黑白两种颜色. 对于每个非叶子节点左子树中的叶子节点 $i$ 和右子树中的叶子节点 $j$ :如果 $i$ 和 $j$ 的 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 017 Android 获取手机SIM卡序列号和读取联系人

    1.获取手机SIM卡序列号 //5.存储sim卡系列号 //5.1获取sim卡系列号 TelephonyManager manager = (TelephonyManager) getSystemSe ...

  2. golang之结构体结构体嵌入和匿名成员

    考虑一个二维的绘图程序,提供了一个各种图形的库,例如矩形.椭圆形.星形和轮形等几何形状.这里是其中两个的定义: type Circle struct { X, Y, Radius int } type ...

  3. unittest之makeSuite\testload\discover及测试报告teseReport

    转载:http://www.cnblogs.com/sunny0/p/7771089.html 测试套件suite除了使用addTest以外,还有使用操作起来更更简便的makeSuite\testlo ...

  4. shell 学习笔记2-shell-test

    一.字符串测试表达式 前面一篇介绍:什么是shell,shell变量请参考: shell 学习笔记1-什么是shell,shell变量 1.字符串测试表达式参数 字符串需要用""引 ...

  5. 关于Mybatis中mapper.xml的传入参数简单技巧

    由于在做项目的时候,我看见同事使用的传入参数类型各式各样,感觉没规律可言,闲暇的时候我就自己搭建了项目做了一些传入参数的测试(当然其实更好的方式是看源码,但是博主能力有限,毕竟入行没多久,看起来很吃力 ...

  6. Python基础初识

    一.安装 暂时没空写,预留 二.python基础初识 2.1 注释 当行注释:# 被注释内容 多行注释:'''被注释内容''',或者"""被注释内容"" ...

  7. Linux:定时任务crond服务

    一.crond简介 crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动cro ...

  8. Python基本数据类型及实例详解

    Python 中的变量不需要声明.每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建. 在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对 ...

  9. 如何去把内容分享到whatsapp上?

    使用场景,公司利用whatsapp来推广商品,需要把商品和一些基本信息分享到WhatsApp上; 一:在html的head标签里面通过meta标签加上一些分享的基本网站信息,具体代码如下 <me ...

  10. 【前端适配】vw单位移动端适配方案

    近些年移动端的强势崛起,导致移动端适配越来越重要,个人之前一直使用的是rem进行适配,但是发现并不是非常完美,给力的是大漠老师写了一篇<如何在Vue项目中使用vw实现移动端适配>,比较完美 ...