Input

第一行包含两个正整数n,m,分别表示这家餐厅提供的寿司总数和计算寿司价格中使用的常数。
第二行包含n个正整数,其中第k个数ak表示第k份寿司的代号。
接下来n行,第i行包含n-i+1个整数,其中第j个数di,i+j-1表示吃掉寿司能
获得的相应的美味度,具体含义见问题描述。
N<=100,Ai<=1000

Output

输出共一行包含一个正整数,表示Kiana能获得的总美味度减去花费的总钱数的最大值。

Sample Input

3 1
2 3 2
5 -10 15
-10 15
15

Sample Output

12
分析:看出来这是一道网络流题,却不知道该如何建模......
   看到mx^2 + cx这个式子,我想起了bzoj1449的费用递增模型. 然而m和x都是固定的,每次的增量都是x,费用并不是递增的......
   然后我又想:选取若干个不同的寿司,它们之间会产生贡献. 似乎可以用最小割来做,类似bzoj3144的离散变量模型吗? 这道题选择的寿司之间没有任何限制,当然不是离散变量模型了. 
   单纯考虑最小割可以吗? 每次要求选一段连续的区间不好处理啊.
   上述尝试均失败后,果断打了暴力.
   如果把区间看作点,这道题差不多就做完了. 选择了区间[l,r],则必然会选择在[l,r]中的所有的点,这实际上就是最大权闭合子图模型. 每个区间要向所有区间内的点连边吗? 不用!利用传递关系:[l,r]向[l + 1,r]和[l,r - 1]连边.  当l == r时,就代表了一个点.
   费用要怎么处理呢? 将mx^2 + cx看作mx^2 和 cx两部分. 把编号也看作点. 如果一个编号被选择了,那么它的费用就是mx^2,不会改变.  如果一个点被选择了,那么它的费用就是它的编号.  所以每个编号向T连边,容量为m * i^2. 每个点向其所属的编号连边, 容量为inf.  每个点向T连边,容量为其编号.  这样的话选择了点i,就要割掉它到T的所有连边,即i的编号与T的连边和i与T的连边.
   具体的建图方式如下:

(参考sliverNebula的博客)

    可以这么理解:割掉S与点i的边,就是放弃了i.  割掉i与T的连边,就是选i的代价.

   做网络流的题要有把所有东西都看作“点”的想法.

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = ,maxm = ,inf = 0x7fffffff;
int n,m,a[],mx,d[][],cnt,pos[][],S,T,ans,head[maxn];
int to[maxm],nextt[maxm],w[maxm],tot = ,vis[maxn],cur[maxn]; void add(int x,int y,int z)
{
w[tot] = z;
to[tot] = y;
nextt[tot] = head[x];
head[x] = tot++; w[tot] = ;
to[tot] = x;
nextt[tot] = head[y];
head[y] = tot++;
} bool bfs()
{
queue <int> q;
q.push(S);
memset(vis,-,sizeof(vis));
vis[S] = ;
while (!q.empty())
{
int u = q.front();
q.pop();
if (u == T)
return true;
for (int i = head[u];i;i = nextt[i])
{
int v = to[i];
if (w[i] && vis[v] == -)
{
vis[v] = vis[u] + ;
q.push(v);
}
}
}
return false;
} int dfs(int u,int f)
{
if (u == T)
return f;
int res = ;
for (int i = cur[u];i;i = nextt[i])
{
int v = to[i];
if (w[i] && vis[v] == vis[u] + )
{
int temp = dfs(v,min(f - res,w[i]));
w[i] -= temp;
w[i ^ ] += temp;
res += temp;
if (w[i])
cur[u] = i;
if (res == f)
return res;
}
}
if (!res)
vis[u] = -;
return res;
} void dinic()
{
while (bfs())
{
for (int i = ; i <= T; i++)
cur[i] = head[i];
ans -= dfs(S,inf);
}
} int main()
{
scanf("%d%d",&n,&m);
for (int i = ; i <= n; i++)
{
scanf("%d",&a[i]);
mx = max(mx,a[i]);
}
cnt = mx + n;
for (int i = ; i <= n; i++)
for (int j = i; j <= n; j++)
{
if (i == j)
pos[i][j] = i;
else
pos[i][j] = ++cnt;
}
S = cnt + ;
T = S + ;
for (int i = ; i <= n; i++)
for (int j = ; j <= n - i + ; j++)
{
scanf("%d",&d[i][i + j - ]);
int l = i,r = i + j - ;
if (d[l][r] < )
add(pos[l][r],T,-d[l][r]);
else
{
add(S,pos[l][r],d[l][r]);
ans += d[l][r];
}
if (l != r)
add(pos[l][r],pos[l + ][r],inf),add(pos[l][r],pos[l][r - ],inf);
else
{
add(pos[l][r],a[l] + n,inf);
add(pos[l][r],T,a[l]);
}
}
for (int i = ; i <= mx; i++)
add(i + n,T,i * i * m);
dinic();
printf("%d\n",ans); return ;
}

bzoj4873 [Shoi2017]寿司餐厅的更多相关文章

  1. 【最大权闭合子图】bzoj4873 [Shoi2017]寿司餐厅

    4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 369  Solved: 256[Submit][Status ...

  2. bzoj4873: [Shoi2017]寿司餐厅(最大权闭合子图)

    4873: [Shoi2017]寿司餐厅 大难题啊啊!!! 题目:传送门 题解:一眼题是网络流,但还是不会OTZ,菜啊... %题解... 最大权闭合子图!!! 好的...开始花式建边: 1.对于每个 ...

  3. BZOJ4873[Shoi2017]寿司餐厅——最大权闭合子图

    题目描述 Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个 代号ai和美味度di,i,不同种类的寿司有可能使用相同的代号.每种寿司的份数都是无 ...

  4. BZOJ4873 Shoi2017寿司餐厅(最小割)

    选择了某个区间就必须选择其所有子区间,容易想到这是一个最大权闭合子图的模型.考虑将区间按长度分层,相邻层按包含关系连边,区间[i,j]的权值即di,j,其中最后一层表示长度为1的区间的同时也表示寿司本 ...

  5. BZOJ4873 [Shoi2017]寿司餐厅 【最大权闭合子图】

    题目链接 BZOJ4873 题解 题意很鬼畜,就可以考虑网络流[雾] 然后就会发现这是一个裸的最大权闭合子图 就是注意要离散化一下代号 #include<algorithm> #inclu ...

  6. bzoj4873: [Shoi2017]寿司餐厅(最小割)

    传送门 大佬们是怎么一眼看出这是一个最大权闭合子图的……大佬好强->这里 1.把所有区间$(i,j)$看成一个点,如果权值大于0,则从$S$向他连边,容量为权值,否则从它向$T$连边,容量为权值 ...

  7. 【BZOJ4873】[Shoi2017]寿司餐厅 最大权闭合图

    [BZOJ4873][Shoi2017]寿司餐厅 Description Kiana最近喜欢到一家非常美味的寿司餐厅用餐.每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个代号ai和美味度di ...

  8. BZOJ:4873: [Shoi2017]寿司餐厅

    4873: [Shoi2017]寿司餐厅 首先很开心在膜你赛的时候做了出来. 看到数据范围,看到不能dp,看到贡献去重后计算,咦,流? 那就容易了,转最大权闭合子图,每个区间建一个点,取了就一定要取他 ...

  9. bzoj 4873: [Shoi2017]寿司餐厅 [最小割]

    4873: [Shoi2017]寿司餐厅 题意:略 唯一会做的... 一眼最小割 就是最大权闭合子图呀 \(s\rightarrow d_{positive} \rightarrow -d_{negt ...

随机推荐

  1. C#匿名参数(转载too)

    匿名方法是在初始化委托时内联声明的方法. 例如下面这两个例子: 不使用匿名方法的委托: using System; using System.Collections.Generic; using Sy ...

  2. Hyper-V虚拟机联网设置

    转自:http://www.3lian.com/edu/2012/12-22/50492.html Windows 8中内置的Hyper-V管理器可以说给许多人带来了惊喜!在Hyper-V管理器强大的 ...

  3. Python-2.7 配置tab自动补全功能

    作者博文地址:http://www.cnblogs.com/spiritman/ 之前一直使用shell编程,习惯了shell的 tab 自动补全功能,而Python的命令行却不支持 tab 自动补全 ...

  4. Codeforces Round #613 Div.1 D.Kingdom and its Cities 贪心+虚树

    题目链接:http://codeforces.com/contest/613/problem/D 题意概述: 给出一棵树,每次询问一些点,计算最少删除几个点可以让询问的点两两不连通,无解输出-1.保证 ...

  5. Scrum立会报告+燃尽图(Beta阶段第二周第四次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2412 项目地址:https://coding.net/u/wuyy694 ...

  6. Beta阶段第一次网络会议

    Beta阶段第一次网络会议 游戏问题 游戏细节特征不够明显,大小虽然随着电脑分辨率的不同变化着,但是存在清楚的问题 游戏中的提示信息不够,玩家无法快速了解游戏 游戏中背景声音过于单一 游戏AI太简单 ...

  7. ASP.NET MVC5 学习系列之模型绑定

    一.理解 Model Binding Model Binding(模型绑定) 是 HTTP 请求和 Action 方法之间的桥梁,它根据 Action 方法中的 Model 类型创建 .NET 对象, ...

  8. 第15章 磁盘配额(Quota)与高级文件系统管理

    磁盘配额(quota)的应用与实践 什么是quota 举例来说,用户的默认主文件夹是在/home下面,如果/home是个独立的分区,假设是10G,/home下有30个账号,这样30个用户共享这10G的 ...

  9. 使用rand替换random模块

    random模块使用相同的种子,在不同的进程中会出现相同的结果. rand的模块使用不同的种子,在不同的进程中不会出现相同的结果. 2个模块都是erlang自带的. 然后erlang在文档里面注明推荐 ...

  10. vue知识拓展

    组件 *组件里面如果要放数据:        data必须是函数的形式,函数必须返回一个对象(json),有的时候我们自己创建的组件需要使用到自己的数据,此外组建中也可以放入自己的其他的比如事件之类的 ...