题意

给定一棵满二叉树,每个叶节点有一个状态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. todo---git 生成密钥 原理分析

    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRJkDZ2z7syFC2QDCaORKF41ecwbL/kyFwkycOVE3MavTRBliAhoAhOaZQTr4j ...

  2. PAT(B) 1088 三人行(Java)

    题目链接:1088 三人行 (20 point(s)) 参考博客:PAT (Basic Level) Practice (中文)1088 三人行 (20 分)(Java实现)吃口雪花 题目描述 子曰: ...

  3. WUSTOJ 1326: Graph(Java)费马数

    题目链接:1326: Graph 参考博客:HNUSTOJ-1617 Graph(费马数)--G2MI Description Your task is to judge whether a regu ...

  4. 嵌入式Linux学习笔记之第二阶段---文件I/O

    1.文件IO的四个函数 一些术语: 不带缓冲的I/O: 每个read和write都调用内核中的一个系统调用. 文件描述符: 一个非负整数,对内核而言,所以打开的文件都通过文件描述符引用. ①打开或创建 ...

  5. c++实现双端队列

    在使用c++容器的时候其底层如何实现  例如  vector 容器  :是一个内存可以二倍扩容的向量容器,使用方便但是对内存要求严格,弊端明显    list  容器  : 双向循环链表    deq ...

  6. CentOS6.8 克隆

    克隆 克隆前,先将上面安装好并且设置好的系统关机 (1) 右键centos -->管理->克隆->下一步->下一步->完整克隆 ->克隆名称起名有意义点就行-> ...

  7. X86驱动:恢复SSDT内核钩子

    SSDT 中文名称为系统服务描述符表,该表的作用是将Ring3应用层与Ring0内核层,两者的API函数连接起来,起到承上启下的作用,SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用 ...

  8. markdown语法之列表与缩进

    在markdown语法中, 用*或+或-在行首表示无序列表.在这些符号之后应该空一格然后输入内容. 例如 + 无序列表 * 无序列表 - 无序列表 会被markdown语法渲染为 无序列表 列表嵌套 ...

  9. JDK8源码解析 -- HashMap(一)

    最近一直在忙于项目开发的事情,没有时间去学习一些新知识,但用忙里偷闲的时间把jdk8的hashMap源码看完了,也做了详细的笔记,我会把一些重要知识点分享给大家.大家都知道,HashMap类型也是面试 ...

  10. SQL Server的非聚集索引中会存储NULL吗?

    原文:SQL Server的非聚集索引中会存储NULL吗? SQL Server的非聚集索引中会存储NULL吗? 这是个很有意思的问题,下面通过如下的代码,来说明,到底会不会存储NULL. --1.建 ...