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

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

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

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. 安装bitcore

    官网----------------------------------------------https://bitcore.io先安装好 node.js v4,  npmsudo npm inst ...

  2. 《深入浅出深度学习:原理剖析与python实践》第八章前馈神经网络(笔记)

    8.1 生物神经元(BN)结构 1.人脑中有100亿-1000亿个神经元,每个神经元大约会和其他1万个神经元相连 2.细胞体:神经元的主体,细胞体=细胞核+细胞质+细胞膜,存在膜电位 3.树突:从细胞 ...

  3. 贪心 Radar Installation (求最少探测雷达)

    Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea i ...

  4. Vertex&Frag

    一.Vertex&Frag 包含Vertex&Fragment 的Shader叫做顶点&像素着色器,在Vertex的功能函数中,我们侧重于几何计算,如纹理坐标,顶点坐标等:在F ...

  5. 细说php第八章笔记(初稿)

    8.1 函数的定义      函数是被命名的:      函数是独立的:      函数执行特定的任务:      函数可以用将一个返回值返回给调用他的程序 函数的优越性      提高程序的重用性 ...

  6. Fiddler抓取https相关设置

    转自:https://www.cnblogs.com/joshua317/p/8670923.html 很多使用fiddler抓包,对于http来说不需太多纠结,随便设置下就能用,但是抓取https就 ...

  7. POJ-1274The Perfect Stall,二分匹配裸模板题

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23313   Accepted: 103 ...

  8. HDU 4473

    题目大意: 给定一个long long 型的数 n,找到一共有多少对a,b,使比n小的某一个数的是a*b的倍数 这样我们可以理解为 存在a*b*c <= n,令 a <= b <= ...

  9. hdu 4871 树的分治+最短路记录路径

    /* 题意:给你一些节点和一些边,求最短路径树上是k个节点的最长的路径数. 解:1.求出最短路径树--spfa加记录 2.树上进行操作--树的分治,分别处理子树进行补集等运算 */ #include& ...

  10. hdu - 1394 Minimum Inversion Number(线段树水题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...