【BZOJ1495】[NOI2006]网络收费

Description

网络已经成为当今世界不可或缺的一部分。每天都有数以亿计的人使用网络进行学习、科研、娱乐等活动。然而,不可忽视的一点就是网络本身有着庞大的运行费用。所以,向使用网络的人进行适当的收费是必须的,也是合理的。MY市NS中学就有着这样一个教育网络。网络中的用户一共有2N个,编号依次为1, 2, 3, …, 2N。这些用户之间是用路由点和网线组成的。用户、路由点与网线共同构成一个满二叉树结构。树中的每一个叶子结点都是一个用户,每一个非叶子结点(灰色)都是一个路由点,而每一条边都是一条网线(见下图,用户结点中的数字为其编号)

MY网络公司的网络收费方式比较奇特,称为“配对收费”。即对于每两个用户i, j (1≤i < j ≤2N ) 进行收费。由于用户可以自行选择两种付费方式A、B中的一种,所以网络公司向学校收取的费用与每一位用户的付费方式有关。该费用等于每两位不同用户配对产生费用之和。 为了描述方便,首先定义这棵网络树上的一些概念: 祖先:根结点没有祖先,非根结点的祖先包括它的父亲以及它的父亲的祖先; 管辖叶结点:叶结点本身不管辖任何叶结点,非叶结点管辖它的左儿子所管辖的叶结点与它的右儿子所管辖的叶结点; 距离:在树上连接两个点之间的用边最少的路径所含的边数。 对于任两个用户i, j (1≤i)

由于最终所付费用与付费方式有关,所以NS中学的用户希望能够自行改变自己的付费方式以减少总付费。然而,由于网络公司已经将每个用户注册时所选择的付费方式记录在案,所以对于用户i,如果他/她想改变付费方式(由A改为B或由B改为A),就必须支付Ci元给网络公司以修改档案(修改付费方式记录)。 现在的问题是,给定每个用户注册时所选择的付费方式以及Ci,试求这些用户应该如何选择自己的付费方式以使得NS中学支付给网络公司的总费用最少(更改付费方式费用+配对收费的费用)。

Input

输入文件中第一行有一个正整数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

Output

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

Sample Input

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

Sample Output

8

HINT

【样例说明】 将1号用户的付费方式由B改为A,NS中学支付给网络公司的费用达到最小

题解:先观察表格,发现当nA<nB时,我们可以将选A看成系数为1,选B看成系数为0,这样就可以将点对的贡献拆开来考虑。为此我们预处理cost[i][j],表示i与所有和i的lca深度为j的点构成的点对费用之和,这样我们就相当于将花费都放到了叶子节点处。

但是我们需要知道每个点是nA<nB还是nA>=nB才能确定叶子节点的费用,但由于是完全二叉树,所以我们可以枚举每个节点是nA<nB还是nA>=nB,然后就能确定叶子节点的取A或B的费用,接着用f[x][y]表示x子树中有y个B,其余都是A的最小费用,那么从将一个非叶子节点的两个儿子的DP值进行背包合并便得到了该点的DP值。由于我们已经钦定了该点是nA<nB或是nA>=nB,所以我们在DP时将不合法的状态去掉即可。

以上做法看起来可能比较暴力,不过实际复杂度呢?$T(n)=4(n-1)+2^{2n}$,所以每一层的复杂度都是$O(2^{2n})$的,一共log层;而搜一次叶子节点消耗的时间是n,每个叶子都要被搜到$O(2^n)$次,一共$2^n$个叶子,所以两个地方的复杂度都是$O(2^{2n}n)$的。

然而正解是把我的暴力改成状压。。。都差不多。

goubiGXZ交我程序还加读入优化拿Rank1。

#include <cstdio>
#include <cstring>
#include <iostream>
#define ls x<<1
#define rs x<<1|1
using namespace std;
const int maxn=2100;
typedef long long ll;
int n;
ll ans;
int tp[maxn],B[20],s[20];
ll cost[maxn][12],f[maxn][maxn],C[maxn][2];
inline int lca(int a,int b)
{
int i;
for(i=n-1;i>=0;i--) if((a>>i)!=(b>>i)) break;
return n-i-1;
}
inline int rd()
{
int ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
void dfs(int x,int dep)
{
if(dep==n)
{
f[x][0]=C[x-B[n]][0];
f[x][1]=C[x-B[n]][1];
for(int i=0;i<dep;i++) f[x][s[i]^1]+=cost[x-B[n]][i];
return ;
}
s[dep]=0;
memset(f[x],0x3f,sizeof(f[x][0])*(B[n-dep]+1));
dfs(ls,dep+1),dfs(rs,dep+1);
for(int i=0;i<=B[n-dep-1];i++) for(int j=0;i+j<=B[n-dep-1];j++) f[x][i+j]=min(f[x][i+j],f[ls][i]+f[rs][j]);
s[dep]=1;
dfs(ls,dep+1),dfs(rs,dep+1);
for(int i=1;i<=B[n-dep-1];i++) for(int j=B[n-dep-1]+1-i;j<=B[n-dep-1];j++) f[x][i+j]=min(f[x][i+j],f[ls][i]+f[rs][j]);
}
int main()
{
//freopen("network.in","r",stdin);
//freopen("network.out","w",stdout);
n=rd();
int i,j,v,a;
for(i=0;i<=n;i++) B[i]=1<<i;
for(i=0;i<B[n];i++) tp[i]=rd();
for(i=0;i<B[n];i++) C[i][tp[i]]=0,C[i][tp[i]^1]=rd();
for(i=0;i<B[n];i++) for(j=i+1;j<B[n];j++)
{
a=lca(i,j),v=rd();
cost[i][a]+=v,cost[j][a]+=v;
}
dfs(1,0);
ans=1ll<<60;
for(i=0;i<=B[n];i++) ans=min(ans,f[1][i]);
printf("%lld",ans);
return 0;
}

【BZOJ1495】[NOI2006]网络收费 暴力+DP的更多相关文章

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

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

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

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

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

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

  4. BZOJ1495 [NOI2006]网络收费

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. hibernate中一些属性对操作的影响

    1 inverse,在一对多中使用,表示是否有关联关系控制权.对于保存.删除数据有影响. 2 cascade,表示级联操作 save-update 表示级联保存和更新 delete 表示级联删除 al ...

  2. IronPython使用

    C#: class Program { static void Main(string[] args) { ScriptEngine engine = Python.CreateEngine(); S ...

  3. Atitit.数据库事务隔离级别 attilax 总结

    Atitit.数据库事务隔离级别 1. 事务隔离级别的作用 1 2. 在的隔离级别 2 3. 常见数据库的默认管理级别 3 1. 事务隔离级别的作用 较低的隔离级别可以增强许多用户同时访问数据的能力, ...

  4. java的装箱拆箱是什么?

    是什么? 自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱. 为什么 把 ...

  5. HDU 2844 Coin 多重背包

    Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. storyboard三种sugue 和 跳转场景的三种方式 以及控制器之间的传值

    Storyboard引入了2个概念:1. scene:一个场景,由一个viewController和相关的xib表示. 2. segue:在这是用于连接scenes,其有多种类型,iphone包括:P ...

  7. 基础地图Android SDK

    开发者可利用SDK提供的接口,使用百度为您提供的基础地图数据.目前百度地图SDK所提供的地图等级为3-21级,所包含的信息有建筑物.道路.河流.学校.公园等内容. V3.7.0起,地图支持缩放至21级 ...

  8. gdb,程序调试助手

    启动GDB:(其中我的app是编译之后的可执行文件) 退出命令:quit或者简写q 帮助获取: gdb通过完备的在线帮助,使我们使用起来更加方便.所有的帮助信息都是通过help命令获得的,运行help ...

  9. 基于HTML5堆木头游戏

    今天要来分享一款很经典的HTML5游戏——堆木头游戏,这款游戏的玩法是将木头堆积起来,多出的部分将被切除,直到下一根木头无法堆放为止.这款HTML5游戏的难点在于待堆放的木头是移动的,因此需要你很好的 ...

  10. 跟着百度学习php之ThinkPHP的运行流程-2

    Thinkphp为了提高编译的效率,第一次运行的时候thinkphp会把文件全部编译到temp目录下的~runtime.php文件,在第二次运行的时候会直接读取这个文件.所以我们在线下自己写代码测试的 ...