寿司餐厅

时间限制: 1 Sec  内存限制: 512 MB
提交: 6  解决: 3
[提交][状态][讨论版]

题目描述

Kiana 最近喜欢到一家非常美味的寿司餐厅用餐。
每天晚上,这家餐厅都会按顺序提供n种寿司,第i种寿司有一个代号 ai和美味度 di,i,不同种类的寿司有可能使用相同的代号。每种寿司的份数都是无限的,Kiana 也可以无限次取寿司来吃,但每种寿司每次只能取一份,且每次取走的寿司必须是按餐厅提供寿司的顺序连续的一段,即 Kiana 可以一次取走第 1,2种寿司各一份,也可以一次取走第 2,3种寿司各一份,但不可以一次取走第 1,3种寿司。
由于餐厅提供的寿司种类繁多,而不同种类的寿司之间相互会有影响:三文鱼寿司和鱿鱼寿司一起吃或许会很棒,但和水果寿司一起吃就可能会肚子痛。因此,Kiana 定义了一个综合美味度 di,j (i<j),表示在一次取的寿司中,如果包含了餐厅提供的从第i份到第j份的所有寿司,吃掉这次取的所有寿司后将获得的额外美味度。由于取寿司需要花费一些时间,所以我们认为分两次取来的寿司之间相互不会影响。注意在吃一次取的寿司时,不止一个综合美味度会被累加,比如若 Kiana 一次取走了第 1,2,3种寿司各一份,除了 d1,3以外,d1,2,d2,3也会被累加进总美味度中。
神奇的是,Kiana 的美食评判标准是有记忆性的,无论是单种寿司的美味度,还是多种寿司组合起来的综合美味度,在计入 Kiana 的总美味度时都只会被累加一次。比如,若 Kiana 某一次取走了第 1,2种寿司各一份,另一次取走了第 2,3种寿司各一份,那么这两次取寿司的总美味度为 d1,1+d2,2+d3,3+d1,2+d2,3,其中 d2,2只会计算一次。
奇怪的是,这家寿司餐厅的收费标准很不同寻常。具体来说,如果 Kiana 一共吃过了 c (c>0)种代号为x的寿司,则她需要为这些寿司付出 mx2+cx元钱,其中m是餐厅给出的一个常数。
现在 Kiana 想知道,在这家餐厅吃寿司,自己能获得的总美味度(包括所有吃掉的单种寿司的美味度和所有被累加的综合美味度)减去花费的总钱数的最大值是多少。由于她不会算,所以希望由你告诉她。

输入

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

输出

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

样例输入

  1. 3 1
  2. 2 3 2
  3. 5 -10 15
  4. -10 15
  5. 15

样例输出

  1. 12

提示

对于所有数据,保证 −500≤di,j≤500。

【题意】有n种寿司,每一种有无数个,每种寿司编号在有个编号,编号可能相同,现在吃寿司,你可以按照1~k在其中取一段连续的顺序吃,有一个额外美味 度,单独吃也有单独的美味度,每一种编号x的寿司吃完耗费m*x*x,问美味度-耗费最大值。

【分析】最大权闭合子图,指的是对于一张有向图,每个顶点都有一个权值,可正可负。有u->v,当你选择了u就必须选择v,现在要选择一些顶点,使得所得的权值最大。做法就是网络流,源点向所有正权值连边,边容量为顶点权值,所有负权值向汇点连边,边容量为权值的绝对值,,原图中边的容量为inf。跑网络流求最小割,然后答案为正权值之和-最小割。

对于出题人的数据,我们可以换个姿势来看:

5 -10 15

-10 15

15

可以看出每次选择都是一个直角三角形。

那么对于每个点(i,j) (j>i),如果它被选择,那么点(i,j-1)和点(i+1,j)也一定被选择,以此类推。

根据这个来建一个点权图。

对于点(i,j) (j>i),点权为d[i][j],并向点(i,j-1)和点(i+1,j)连边。

对于点(i,i),点权为d[i][i]-a[i],即收益减去费用,并向编号a[i]连边。

对于编号p,点权为-m*p*p。

所求为最大权闭合图,所以转化为网络流最小割来求。

具体建图方法不用像上面说的先建点权图,直接建立网络图即可

  1. #include <bits/stdc++.h>
  2. #define inf 0x3f3f3f3f
  3. #define met(a,b) memset(a,b,sizeof a)
  4. #define pb push_back
  5. #define mp make_pair
  6. #define inf 0x3f3f3f3f
  7. using namespace std;
  8. typedef long long ll;
  9. const int N = 1e5+;
  10. const int mod = 1e9+;
  11. const double pi= acos(-1.0);
  12. typedef pair<int,int>pii;
  13. int n,m,k,f;
  14. int a[],d[][],An=;
  15. int num[][],cnt,ans;
  16. struct Edge{
  17. int from,to,cap,flow;
  18. Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
  19. };
  20. struct Dinic{
  21. int s,t;
  22. vector<Edge>edges;
  23. vector<int> G[N];
  24. bool vis[N];
  25. int d[N];
  26. int cur[N];
  27. void init(){
  28. for (int i=;i<=n+;i++)
  29. G[i].clear();
  30. edges.clear();
  31. }
  32. void AddEdge(int from,int to,int cap){
  33. edges.push_back(Edge(from,to,cap,));
  34. edges.push_back(Edge(to,from,,));
  35. int mm=edges.size();
  36. G[from].push_back(mm-);
  37. G[to].push_back(mm-);
  38. }
  39. bool BFS(){
  40. memset(vis,,sizeof(vis));
  41. queue<int>q;
  42. q.push(s);
  43. d[s]=;
  44. vis[s]=;
  45. while (!q.empty()){
  46. int x = q.front();q.pop();
  47. for (int i = ;i<G[x].size();i++){
  48. Edge &e = edges[G[x][i]];
  49. if (!vis[e.to] && e.cap > e.flow){
  50. vis[e.to]=;
  51. d[e.to] = d[x]+;
  52. q.push(e.to);
  53. }
  54. }
  55. }
  56. return vis[t];
  57. }
  58.  
  59. int DFS(int x,int a){
  60. if (x==t || a==)
  61. return a;
  62. int flow = ,f;
  63. for(int &i=cur[x];i<G[x].size();i++){
  64. Edge &e = edges[G[x][i]];
  65. if (d[x]+ == d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>){
  66. e.flow+=f;
  67. edges[G[x][i]^].flow-=f;
  68. flow+=f;
  69. a-=f;
  70. if (a==)
  71. break;
  72. }
  73. }
  74. return flow;
  75. }
  76.  
  77. int Maxflow(int s,int t){
  78. this->s=s;
  79. this->t=t;
  80. int flow = ;
  81. while (BFS()){
  82. memset(cur,,sizeof(cur));
  83. flow+=DFS(s,inf);
  84. }
  85. return flow;
  86. }
  87. }dc;
  88. int main(){
  89. scanf("%d%d",&n,&m);
  90. for(int i=;i<=n;i++)scanf("%d",&a[i]);
  91. int S=,T=1e5;
  92. dc.init();
  93. for(int i=;i<=An;i++){
  94. dc.AddEdge(i,T,m*i*i);
  95. }
  96. for(int i=;i<=n;i++){
  97. for(int j=i;j<=n;j++){
  98. scanf("%d",&d[i][j]);
  99. num[i][j]=An+(++cnt);
  100. }
  101. }
  102. for(int i=;i<=n;i++){
  103. for(int j=i;j<=n;j++){
  104. if(i==j){
  105. d[i][j]-=a[i];
  106. dc.AddEdge(num[i][i],a[i],inf);
  107. }
  108. else{
  109. dc.AddEdge(num[i][j],num[i][j-],inf);
  110. dc.AddEdge(num[i][j],num[i+][j],inf);
  111. }
  112. if(d[i][j]<){
  113. dc.AddEdge(num[i][j],T,-d[i][j]);
  114. }
  115. else {
  116. dc.AddEdge(S,num[i][j],d[i][j]);
  117. ans+=d[i][j];
  118. }
  119. }
  120. }
  121. printf("%d\n",ans-dc.Maxflow(S,T));
  122. return ;
  123. }

BZOJ 4873 寿司餐厅(最大权闭合图 网络流)的更多相关文章

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

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

  2. POJ 3155 Hard Life 最大密度子图 最大权闭合图 网络流 二分

    http://poj.org/problem?id=3155 最大密度子图和最大权闭合图性质很相近(大概可以这么说吧),一个是取最多的边一个是取最多有正贡献的点,而且都是有选一种必须选另一种的限制,一 ...

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

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

  4. [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)

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

  5. [HEOI2017] 寿司餐厅 + 最大权闭合子图的总结

    Description 太长了自己看叭 点这里! Solution 先学一波什么叫最大权闭合子图. 先要明白什么是闭合子图,闭合子图就是给定一个有向图,从中选择一些点组成一个点集V.对于V中任意一个点 ...

  6. BZOJ 4873 寿司餐厅 网络流

    最大权闭合子图 1.每个区间收益(i,j)对应一个点 权值为正连S 负连T 2.每个区间收益向其子区间收益(i+1,j)与(i,j-1)对应的两个点连边 容量为INF 3.每个寿司类型对应一个点 连一 ...

  7. BZOJ 1565 植物大战僵尸 最大权闭合子图+网络流

    题意: 植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: (1)价值: (2)保护集合,也就是这个植物可以保护矩阵中的某些格子. 现在你是僵尸,你每次只能从(i,m) 格子 ...

  8. BZOJ 1497 最大获利(最大权闭合图)

    1497: [NOI2006]最大获利 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 4686  Solved: 2295 [Submit][Statu ...

  9. HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)

    http://acm.hdu.edu.cn/showproblem.php?pid=3879 http://www.lydsy.com/JudgeOnline/problem.php?id=1497 ...

随机推荐

  1. [洛谷P3401] 洛谷树

    洛谷题目连接:洛谷树 题目背景 萌哒的Created equal小仓鼠种了一棵洛谷树! (题目背景是辣鸡小仓鼠乱写的QAQ). 题目描述 树是一个无环.联通的无向图,由n个点和n-1条边构成.树上两个 ...

  2. 两小时快速构建微信小程序

    小程序在2017年1月上线之初,被社会极力吹捧,刻意去将其制造为一个“风口”,透支其价值.但是在之后一个月里,石破天惊迅速归为沉寂.媒体又开始过度消费小程序,大谈其鸡肋之处. 个人认为小程序的一个分水 ...

  3. Desert King(POJ2728+最优比率生成树+二分)

    题目链接:http://poj.org/problem?id=2728 题目: 题意:求一颗生成树,使得费用与距离的比值最小,其中距离等于两点之间的平面欧拉距离,费用为z坐标之差. 思路: 由上图我们 ...

  4. eclipse执行maven install命令时跳过test

    在pom.xml里面配置一下代码,将跳过test. <plugins> <plugin> <groupId>org.apache.maven.plugins< ...

  5. perl输出重定向

    use utf8; open A, ">&STDOUT"; open STDOUT, ">AA.txt"; print STDOUT 'AB ...

  6. metlnfo 5.3.1 sql注入复现

    首先还是要说的是metlnfo是伪全局变量机制 所以如下: /admin/include/global.func.php function save_met_cookie(){ global $met ...

  7. 使用UpdatePanel时FileUpload失效的问题

    出处:http://www.cnblogs.com/caicainiao/archive/2010/12/08/1900377.html 1.使用UpdatePanel后,FileUpload的Has ...

  8. 算法题之Median of Two Sorted Arrays

    这道题是LeetCode上的题目,难度级别为5,刚开始做没有找到好的思路,以为是自己智商比较低,后来发现确实也比较低... 题目: There are two sorted arrays nums1  ...

  9. 【学习笔记】动态树Link-Cut-Tree

    这是两个月前写的,看能不能搬运过来…… 动态树是一类维护森林连通性的问题(已纠正,感谢ZQC巨佬),目前最(wo)常(zhi)见(hui)的动态树就是LCT(Link-Cut-Tree),然而LCT似 ...

  10. 设计模式之笔记--抽象工厂模式(Abstract Factory)

    抽象工厂模式(Abstract Factory) 定义 抽象工厂模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 类图 描述 多个抽象产品 ...