学姐的逛街计划


描述


doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课.
偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天.

doc 很忧伤, 因为他还要陪学姐去逛街呢.

后来, doc发现, 如果自己哪一天智商更高一些, 陪学姐逛街会得到更多的好感度.
现在 doc 决定做一个实验来验证自己的猜想, 他拜托 小岛 预测出了 自己 未来 3n 天中, 每一天的智商.
doc 希望在之后的 3n 天中选出一些日子来陪学姐逛街, 要求在不违反校规的情况下, 陪学姐逛街的日子自己智商的总和最大.

可是, 究竟这个和最大能是多少呢?

格式


输入格式


第一行给出两个整数, n 和 k, 表示我们需要设计之后 3n 天的逛街计划, 且任意连续 n 天中不能请假超过 k 天.
第二行给出 3n 个整数, 依次表示 doc 每一天的智商有多少. 所有数据均为64位无符号整数

输出格式


输出只有一个整数, 表示可以取到的最大智商和.

样例1


样例输入1


样例输出1

  1.  

限制


对于 20% 的数据, 1 <= n <= 12 , k = 3.
对于 70% 的数据, 1 <= n <= 40 .
对于 100% 的数据, 1 <= n <= 200 , 1 <= k <= 10.

                      
分析:

可以记第i天去不去逛街为a[i],第i天智商为val[i];
设:
p[1] = a[1] + a[2] + …… + a[n] <= k;
p[2] = a[2] + a[3] + …… + a[n + 1] <= k
……
p[n * 2 + 1] = a[n * 2 + 1] + a[n * 2 + 2] + …… + a[3 * n] <= k
然后添加辅助变量y[i],设q[i] = p[i] + y[i] = k
可得:
q[1] = p[1] +y[1] = k 
q[2] = p[2] +y[2] = k
……
q[n * 2 + 1] = p[n * 2 + 1] +y[n * 2 + 1] = k
添加 辅助变量 q[0] = 0,q[n * 2 + 2] = 0
依次相减得到:
q[1] - q[0] = a[1] + a[2] + …… + a[n] + y[1] = k; ---- 1
q[2] - q[1] = a[n + 1] - a[1] + y[2] - y[1] = 0; ----2
q[3] - q[2] = a[n + 2] - a[2] + y[3] - y[2] = 0;----3
……
q[n * 2 + 2] - q[n * 2 + 1] = - a[n * 2 + 1] - a[n * 2 + 2] - …… - a[3 * n] - y[n * 2 + 1] = -k;-----n * 2 + 2
可以发现每一个变量都在等式中出现了两次,并且一次为正,一次为负,正相对于网络流中的流量守恒,流进等于流出(实际流量即为变量的值)
于是我们可以把每个等式看成一个点。把源点和第一个点连流量为k,花费为0。汇点和最后一个点连流量为k,花费为0;
对于每一个a[i]把它在等式中为正的点连向它在等式中为负的点,流量为1,花费为-val[i]。(因为求最大费用最大流,花费取负数后答案再倒回来就行)
对于每一个y[i]把它在等式中为正的点连向它在等式中为负的点,流量为k,花费为0。
然后求一遍最小费用最大流,答案取相反数(这样变成了最大费用最大流),就为我们要的答案。
贴上AC代码:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <queue>
  5. using namespace std;
  6. const int N = 1e4;
  7. const int M = 4e5;
  8. const int INF = 0x3f3f3f3f;
  9. using namespace std;
  10. struct Edge
  11. {
  12. int from, to, cap, flow, cost, next;
  13. };
  14. Edge edge[M];
  15. int head[N], inde,pre[N], dist[N];
  16. bool vis[N];
  17. int n,k;
  18. void init()
  19. {
  20. inde = ;
  21. memset(head, -, sizeof(head));
  22. }
  23. void AddEdge(int u, int v, int w, int c)
  24. {
  25. Edge E1 = {u, v, w, , c, head[u]};
  26. edge[inde] = E1;
  27. head[u] = inde++;
  28. Edge E2 = {v, u, , , -c, head[v]};
  29. edge[inde] = E2;
  30. head[v] = inde++;
  31. }
  32. bool SPFA(int s, int t)
  33. {
  34. queue<int> Q;
  35. memset(dist, INF, sizeof(dist));
  36. memset(vis, false, sizeof(vis));
  37. memset(pre, -, sizeof(pre));
  38. dist[s] = ;
  39. vis[s] = true;
  40. Q.push(s);
  41. while(!Q.empty())
  42. {
  43. int u = Q.front();
  44. Q.pop();
  45. vis[u] = false;
  46. for(int i = head[u]; i != -; i = edge[i].next)
  47. {
  48. Edge E = edge[i];
  49. if(dist[E.to] > dist[u] + E.cost && E.cap > E.flow)
  50. {
  51. dist[E.to] = dist[u] + E.cost;
  52. pre[E.to] = i;
  53. if(!vis[E.to])
  54. {
  55. vis[E.to] = true;
  56. Q.push(E.to);
  57. }
  58. }
  59. }
  60. }
  61. return pre[t] != -;
  62. }
  63. void MCMF(int s, int t, int &cost, int &flow)
  64. {
  65. flow = ;
  66. cost = ;
  67. while(SPFA(s, t))
  68. {
  69. int Min = INF;
  70. for(int i = pre[t]; i != -; i = pre[edge[i^].to])
  71. {
  72. Edge E = edge[i];
  73. Min = min(Min, E.cap - E.flow);
  74. }
  75. for(int i = pre[t]; i != -; i = pre[edge[i^].to])
  76. {
  77. edge[i].flow += Min;
  78. edge[i^].flow -= Min;
  79. cost += edge[i].cost * Min;
  80. }
  81. flow += Min;
  82. }
  83. }
  84. int cnt,s,t;
  85. int node[],val[];
  86. int st[],en[];
  87. void getMap(){
  88. s = ++cnt;t = ++cnt;
  89. for(int i = ;i <= n * + ;i++){
  90. node[i] = ++cnt;
  91. }for(int i = ;i <= * n;i++)scanf("%d",&val[i]);
  92. AddEdge(s,node[],k,);
  93. AddEdge(node[n * + ],t,k,);
  94. for(int i = ;i <= n;i++)st[i] = node[];
  95. for(int i = n + ;i <= * n;i++)st[i] = node[i - n + ];
  96. for(int i = ;i <= * n;i++)en[i] = node[i + ];
  97. for(int i = * n + ;i <= * n;i++)en[i] = node[n * + ];
  98. for(int i = ;i <= * n;i++)AddEdge(st[i],en[i],,-val[i]);
  99. for(int i = ;i <= * n + ;i++)AddEdge(node[i],node[i + ],k,);
  100. }
  101. int main()
  102. {
  103. scanf("%d %d",&n,&k);
  104. init();
  105. getMap();
  106. int cost, flow;
  107. MCMF(s,t, cost, flow);
  108. printf("%d\n",-cost);
  109. return ;
  110. }

[vijos1891]学姐的逛街计划的更多相关文章

  1. Vijos1891 学姐的逛街计划 【费用流】*

    Vijos1891 学姐的逛街计划 描述 doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课. 偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, ...

  2. vijos1891 学姐的逛街计划(线性规划)

    P1891学姐的逛街计划 描述 doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课.偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, 因为他还要陪 ...

  3. 刷题总结——学姐的逛街计划(vijos1891费用流)

    题目: doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课.偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, 因为他还要陪学姐去逛街呢. 后来, ...

  4. Vijos 学姐的逛街计划

    传送门 题解传送门 线性规划,最小费用最大流. 神奇的操作. //Achen #include<algorithm> #include<iostream> #include&l ...

  5. Vijos1901 学姐的钱包

    描述 学姐每次出门逛街都要带恰好M元钱, 不过她今天却忘记带钱包了.可怜的doc只好自己凑钱给学姐, 但是他口袋里只有一元钱.好在doc的N位朋友们都特别有钱, 他们答应与doc作一些交换.其中第i位 ...

  6. cdoj 1328 卿学姐与诡异村庄 Label:并查集 || 二分图染色

    卿学姐与诡异村庄 Time Limit: 4500/1500MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  7. cdoj 1329 卿学姐与魔法 优先队列

    卿学姐与魔法 Time Limit: 1200/800MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  8. cdoj 1324 卿学姐与公主 线段树裸题

    卿学姐与公主 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  9. vijosP1903学姐的实习工资

    描述 学姐去实习了, 一共实习了N天, 每一天都可以得到实习工资V[i], 这里V[1..N]被看作是整数序列.因为学姐很厉害, 所以V[1..N]是不下降的.也就是说学姐每天的工资只会越来越多, 不 ...

随机推荐

  1. CSData

    NSString 转换成NSData 对象 NSData* xmlData = [@"testdata" dataUsingEncoding:NSUTF8StringEncodin ...

  2. javascript动态添加、修改、删除对象的属性与方法

    在其他语言中,对象一旦生成,就不可更改了,要为一个对象添加修改成员必须要在对应的类中修改,并重新实例化,而且程序必须经过重新编译.JavaScript 中却非如此,它提供了灵活的机制来修改对象的行为, ...

  3. jeecms

    ===标签=== <!-- 显示一级栏目对应的二级栏目 --> <!-- [@cms_channel_list parentId=c.id] [#if tag_list?size&g ...

  4. http请求响应格式

    当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成:l   请求方法URI协议/版本l   请求头(Request Header)l   请求正 ...

  5. vueshengmingzhouqi

    首先,每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期.首先看一张图吧~这是官方文档上的图片相信大家一定都会很熟悉: 可以看到在vue一整个的生命周期中会有很多钩子函 ...

  6. codevs 2853 方格游戏--棋盘dp

    方格游戏:http://codevs.cn/problem/2853/ 这和传纸条和noip方格取数这两个题有一定的相似性,当第一眼看到的时候我们就会想到设计$dp[i][j][k][l]$(i,j表 ...

  7. InnoDB INFORMATION_SCHEMA FULLTEXT Index Tables

    InnoDB INFORMATION_SCHEMA FULLTEXT Index Tables 下表提供了FULLTEXT索引的元数据: mysql> SHOW TABLES FROM INFO ...

  8. linux破解root登录密码,并重置

    重启系统后按'e'键,进入编辑模式,在'UTF -8'后空格输入'rd.break'后,按快捷键'Ctrl+X'进入新界面进行编辑,代码如下: switch_root:/# mount -o remo ...

  9. js中表格的相关操作

    tHead:表头 tBodies:表格正文 tFoot:表格尾 rows:行 cells:列 表格的应用: 1.获取 2.表格创建 3.隔行变色 4.删除一行 <!DOCTYPE html> ...

  10. LeetCode(18)4Sum

    题目 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...