# bzoj 1283 序列 - 费用流

给定一个长度为$n$的序列，要求选出一些数使得原序列中每$m$个连续的数中不超过$K$个被选走。问最大的可能的和。

感觉建图好妙啊。。

考虑把问题转化成选$m$次数，每次选出一个子序列， 要求两次选择的数的下标差至少为$m$。

这个很容易建图就能做。$i$向$\min\{T, i + m\}$连边，容量为1，费用为$a_i$。$i$向$i + 1$连边容量为1，费用为0.

### Code

  1 /**
2  * bzoj
3  * Problem#1283
4  * Accepted
5  * Time: 232ms
6  * Memory: 1436k
7  */
8 #include <iostream>
9 #include <cstdlib>
10 #include <cstdio>
11 #include <queue>
12 using namespace std;
13 typedef bool boolean;
14
15 template <typename T>
16 void pfill(T* pst, const T* ped, T val) {
17     for ( ; pst != ped; *(pst++) = val);
18 }
19
20 typedef class Edge {
21     public:
22         int ed, nx, r, c;
23
24         Edge(int ed = 0, int nx = 0, int r = 0, int c = 0) : ed(ed), nx(nx), r(r), c(c) {    }
25 } Edge;
26
27 typedef class MapManager {
28     public:
29         int* h;
30         vector<Edge> es;
31
32         MapManager() {    }
33         MapManager(int n) {
34             h = new int[(n + 1)];
35             pfill(h, h + n + 1, -1);
36         }
37
38         void addEdge(int u, int v, int r, int c) {
39             es.push_back(Edge(v, h[u], r, c));
40             h[u] = (signed) es.size() - 1;
41         }
42
43         void addArc(int u, int v, int cap, int c) {
46         }
47
48         Edge& operator [] (int p) {
49             return es[p];
50         }
51 } MapManager;
52
53 const signed int inf = (signed) (~0u >> 1);
54
55 typedef class Graph {
56     public:
57         int S, T;
58         MapManager g;
59
60         int *le;
61         int *f, *mf;
62         boolean *vis;
63
64         Graph() {    }
65         // be sure T is the last node
66         Graph(int S, int T) {
67             this->S = S;
68             this->T = T;
69             f = new int[(T + 1)];
70             le = new int[(T + 1)];
71             mf = new int[(T + 1)];
72             vis = new boolean[(T + 1)];
73             pfill(vis, vis + T, false);
74         }
75
76         int spfa() {
77             queue<int> que;
78             pfill(f, f + T + 1, -inf);
79             que.push(S);
80             f[S] = 0, le[S] = -1, mf[S] = inf;
81             while (!que.empty()) {
82                 int e = que.front();
83                 que.pop();
84                 vis[e] = false;
85                 for (int i = g.h[e], eu, w; ~i; i = g[i].nx) {
86                     if (!g[i].r)
87                         continue;
88                     eu = g[i].ed, w = f[e] + g[i].c;
89                     if (w > f[eu]) {
90                         f[eu] = w, le[eu] = i, mf[eu] = min(mf[e], g[i].r);
91                         if (!vis[eu]) {
92                             vis[eu] = true;
93                             que.push(eu);
94                         }
95                     }
96                 }
97             }
98             if (f[T] == -inf)
99                 return inf;
100             int rt = 0;
101             for (int p = T, e; ~le[p]; p = g[e ^ 1].ed) {
102                 e = le[p];
103                 g[e].r -= mf[T];
104                 g[e ^ 1].r += mf[T];
105                 rt += mf[T] * g[e].c;
106             }
107             return rt;
108         }
109
110         int max_cost() {
111             int rt = 0, delta;
112             while ((delta = spfa()) != inf) {
113                 rt += delta;
114 //                cerr << delta << '\n';
115             }
116             return rt;
117         }
118 } Graph;
119
120 int n, m, k;
121
122 inline void solve() {
123     scanf("%d%d%d", &n, &m, &k);
124     Graph graph(0, n + 1);
125     MapManager& g = graph.g;
126     k = min(k, m);
127     g = MapManager(n + 1);
140 }