题目链接:点我啊╭(╯^╰)╮
题目大意:
长度为
n
n
n 的序列,最多取
k
k
k 次
每次可以从中取走一个不下降子序列
求最大的
a
i
a_i
ai 总和
解题思路:
核心:费用流模板题
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const int INF = INT_MAX;
const int maxn = 4e3 + 5;
struct edge {
int to, cap, cost, rev;
edge() {}
edge(int _to, int _cap, int _cost, int _rev):\
to(_to), cap(_cap), cost(_cost), rev(_rev) {}
};
struct Min_Cost_Max_Flow {
int V, h[maxn], dis[maxn], prev[maxn], pree[maxn];
vector <edge> G[maxn];
//调用前初始化
void init(int n) {
V = n;
for(int i=0; i<=V; i++) G[i].clear();
}
void add_edge(int from, int to, int cap, int cost) {
G[from].push_back(edge(to, cap, cost, G[to].size()));
G[to].push_back(edge(from, 0, -cost, G[from].size()-1));
}
//flow是自己传进去的变量,就是最后的最大流,返回的是最小费用
int min_cost_max_flow(int s, int t, int f, int &flow) {
int res = 0; fill(h, h+V+1, 0);
while(f) {
priority_queue<pii, vector<pii>, greater<pii> > q;
fill(dis, dis+V+1, INF);
dis[s] = 0; q.push(pii(0, s));
while(!q.empty()) {
pii now = q.top(); q.pop();
int v = now.second;
if(dis[v] < now.first) continue;
for(int i=0; i<G[v].size(); ++i) {
edge &e = G[v][i];
if(e.cap>0 && dis[e.to]>dis[v]+e.cost+h[v]-h[e.to]) {
dis[e.to] = dis[v]+e.cost+h[v]-h[e.to];
prev[e.to] = v; pree[e.to] = i;
q.push(pii(dis[e.to], e.to));
}
}
}
if(dis[t] == INF) break;
for(int i=0; i<=V; ++i) h[i] += dis[i];
int d = f;
for(int v=t; v!=s; v=prev[v]) d = min(d, G[prev[v]][pree[v]].cap);
f -= d; flow += d; res += d * h[t];
for(int v=t; v!=s; v=prev[v]) {
edge &e = G[prev[v]][pree[v]];
e.cap -= d; G[v][e.rev].cap += d;
}
}
return res;
}
};
int T, n, k, a[maxn], flow;
Min_Cost_Max_Flow MCMF;
int main() {
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &k);
int s = 0, t = 2 * n + 1;
MCMF.init(t);
for(int i=1; i<=n; i++){
scanf("%d", a+i);
MCMF.add_edge(i, i+n, 1, -a[i]);
MCMF.add_edge(s, i, 1, 0);
MCMF.add_edge(i+n, t, 1, 0);
for(int j=1; j<i; j++)
if(a[j] <= a[i]) MCMF.add_edge(j+n, i, 1, 0);
}
printf("%d\n", -MCMF.min_cost_max_flow(s, t, k, flow));
}
}