题目略长,就从大视野上复制了。

听上去好像费用流,然而……

***************************表示略长的题目的分界线************************

1495: [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

***************************表示略长的题目结束了的分界线************************

这么长的题目告诉我们一定要学好政治。

收费方式看上去很复杂,实际上没有想象中那么复杂但是也很复杂,可以看成A少就收所有的A,B少就收所有的B。这样用前缀和就能解决收费的问题了。

根据N<10大概猜到应该是状压dp,进而猜出dp(x,y,z)表示到第x个点,有y个A(或y个B),且祖先的取舍方案为z的收费情况。

那么问题就来了:用dp[x][y][z]表示的话,空间总共要占(2^10)^3!这样空间肯定会出问题。能不能将其中两维合成一维呢?

经过一番不对劲的思考,发现每往下走一层,z就会增加一位,而y的最大值会减少一半。把这两维放在同一维似乎不错。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<cstdlib>
#define maxm 5050
#define maxk 2050
using namespace std;
int dp[maxk][maxm],n,m,c[maxk],f[maxk][maxk];
int li[maxk],ri[maxk], ab[maxk];
int read()
{
int x=,f=;
char ch=getchar();
while(isdigit(ch)== && ch!='-')ch=getchar();
if(ch=='-')f=-;
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
int solve(int x,int y,int z,int l,int r,int lim)
{
li[x]=l,ri[x]=r;
int xi=x,xj=(z<<(lim+))|y;
if(dp[xi][xj]!=-)
{
return dp[xi][xj];
}
if(x>=m)
{
int tab,now=x-m+,sum=c[now]*(ab[now]!=y),lu,ru;
for(int lstu=x,u=x>>;u;lstu=u,u>>=)
{
tab=z&;
z>>=;
lu=(lstu!=(u<<))?li[u]:((li[u]+ri[u])>>)+;
ru=(lstu!=(u<<))?((li[u]+ri[u])>>):ri[u];
sum+=(f[now][ru]-f[now][lu-])*(tab!=y);
}
dp[xi][xj]=sum;
return sum;
}
else
{
int tmp=(z<<)|(y>(<<lim)-y),res=0x7fffffff,mi=(l+r)>>,siz=<<(lim-);
if(siz>y)siz=y;
for(int p=y-siz;p<=siz;p++)
{
int t=solve(x<<,p,tmp,l,mi,lim-)+solve((x<<)+,y-p,tmp,mi+,r,lim-);
res=min(res,t);
}
dp[xi][xj]=res;
return res;
}
}
int main()
{
//cout<<"Boy_next_door is playing game."<<endl;
n=read();
m=<<n;
for(int i=;i<=m;i++)
ab[i]=read();
for(int i=;i<=m;i++)
c[i]=read();
for(int i=;i<=m;i++)
for(int j=i+;j<=m;j++)
{
f[i][j]=read();
f[j][i]=f[i][j];
}
memset(dp,-,sizeof(dp));
for(int i=;i<=m;i++)
for(int j=;j<=m;j++)
f[i][j]=f[i][j-]+f[i][j];
int ans=0x7fffffff;
for(int i=;i<=m;i++)
{
int tmp1=solve(,i,,,m,n);
ans=min(ans,tmp1);
}
cout<<ans;
return ;
}

并不对劲的[noi2006]网络收费的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. BZOJ1495 [NOI2006]网络收费

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

  8. [NOI2006]网络收费

    题面在这里 description 一棵\(2^n\)个叶节点的满二叉树,每个节点代表一个用户,有一个预先的收费方案\(A\)或\(B\); 对于任两个用户 \(i,j(1≤i<j≤2^n)i, ...

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

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

随机推荐

  1. python 1-1模块介绍和使用

    1. 什么是模块 1.1 模块就是一系列功能的集合体 1.1.1 模块有三种来源 1.内置的模块 2.第三方的模块 3.自定义模块 1.1.2 模块的格式: 1.使用Python编写的.py文件 2. ...

  2. 利用WITH AS改写SQL

    报表程序中一段SQL语句. 优化前: 返回:3952 耗时:224s SQL 代码: select to_date(nvl(pro.value, '1900-01-01 00:00:00'), 'YY ...

  3. Buffer.compare()

    Buffer.compare(buf1, buf2) buf1 {Buffer} buf2 {Buffer} 返回:{Number} 比较 buf1 和 buf2 通常用于 Buffer 数组的排序目 ...

  4. django+uwsgi+nginx部署(非常详细)

    django+uwsgi+nginx部署 1.介绍: 在网上看了很多教程,但自己部署了很久都没有成功,这篇博文记录自己所踩过得坑. 2.环境: Ubuntu 16.04.1 LTS (GNU/Linu ...

  5. git clone问题

    中秋节回来上班 竟然忘记带电脑了  ̄□ ̄||还好同事有备用电脑,这要是回去拿估计上午都不用干什么了,用同事电脑当然需要安装环境,下面说一下git上遇到的问题吧 (1)首先我尝试用https方式克隆代码 ...

  6. MSP430F5529时钟系统深究

    1.为什么要进行时钟管理? 时钟系统是一个数字器件的命脉,对于普通的51单片机来说,它的时钟来源只有外部晶振,然后每12个振荡周期完成一个基本操作,所以也叫做12T单片机,但对于当前高级一点的单片机来 ...

  7. SQL SERVER占用CPU过高排查和优化

    操作系统是Windows2008R2 ,数据库是SQL2014 64位. 近阶段服务器出现过几次死机,管理员反馈机器内存使用率100%导致机器卡死.于是做了个监测服务器的软件实时记录CPU数据,几日观 ...

  8. 【04】emmet系列之编辑器

     [01]emmet系列之基础介绍 [02]emmet系列之HTML语法 [03]emmet系列之CSS语法 [04]emmet系列之编辑器 [05]emmet系列之各种缩写 前端开发人员,常用的是s ...

  9. 九度oj 题目1068:球的半径和体积

    题目1068:球的半径和体积 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6148 解决:2269 题目描述: 输入球的中心点和球上某一点的坐标,计算球的半径和体积 输入: 球的中心点和 ...

  10. noip模拟赛 写代码

    分析:这其实就是括号匹配题,一眼贪心题,不过一开始贪错了,以为([)]是合法的......其实括号之间不能嵌套. 一开始的想法是尽量往左边填左括号,因为每种括号的数量都确定了,那么左括号和右括号的数量 ...