题意:给定一个长为n的正整数序列,要求从中取出至多k个不下降序列,使得它们的和最大,求这个和

n<=2e3,k<=10,a[i]<=1e5

思路:极其考验模板,反正我的spfa和zkw都挂了,就拿这题std做dijkstra费用流的板子了

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
typedef pair<ll,ll>P;
#define N 10000
#define M 2100000
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const int MOD=,inv2=(MOD+)/;
double eps=1e-;
int INF=0x7fffffff;;
ll inf=5e13;
int dx[]={-,,,};
int dy[]={,,-,}; struct edge
{
int to,cap,cost,rev;
edge(){}
edge(int a,int b,int c,int d):
to(a),cap(b),cost(c),rev(d){}
}; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} struct MCMF
{
int V,h[N],dis[N],preV[N],preE[N];
vector<edge> g[N]; void init(int n)
{
V=n;
rep(i,,V) g[i].clear();
} void add(int u,int v,int cap,int cost)
{
g[u].pb(edge(v,cap,cost,g[v].size()));
g[v].pb(edge(u,,-cost,g[u].size()-));
} int minc_mf(int S,int T,int f,int &flow)
{
int res=;
fill(h,h++V,);
while(f)
{
priority_queue <PII,vector<PII>, greater<PII> > q;
fill(dis,dis++V,INF);
dis[S]=;
q.push(MP(,S));
while(!q.empty())
{
PII now=q.top(); q.pop();
int u=now.se;
if(dis[u]<now.fi) continue;
for(int i=;i<g[u].size();i++)
{
edge e=g[u][i];
int v=e.to;
if(e.cap>&&dis[v]>dis[u]+e.cost+h[u]-h[v])
{
dis[v]=dis[u]+e.cost+h[u]-h[v];
preV[v]=u;
preE[v]=i;
q.push(MP(dis[v],v));
} }
}
if(dis[T]==INF) break;
rep(i,,V) h[i]+=dis[i];
int t=f,k=T;
while(k!=S)
{
int e=preE[k];
t=min(t,g[preV[k]][preE[k]].cap);
k=preV[k];
}
f-=t; flow+=t; res+=t*h[T];
k=T;
while(k!=S)
{
edge &e=g[preV[k]][preE[k]];
e.cap-=t;
g[k][e.rev].cap+=t;
k=preV[k];
}
}
return res;
}
}mcmf; int num[N][],a[N],S,T,s,flow; int main()
{
int cas=read();
s=;
while(cas--)
{
int n=read(),k=read();
rep(i,,n) a[i]=read();
s=;
rep(i,,n)
{
num[i][]=++s;
num[i][]=++s;
}
S=++s; s++; T=++s;
mcmf.init(s);
mcmf.add(S,S+,k,);
rep(i,,n) mcmf.add(S+,num[i][],,);
rep(i,,n) mcmf.add(num[i][],num[i][],,-a[i]);
rep(i,,n)
rep(j,i+,n)
if(a[j]>=a[i]) mcmf.add(num[i][],num[j][],,);
rep(i,,n) mcmf.add(num[i][],T,,);
flow=;
int ans=-mcmf.minc_mf(S,T,INF,flow);
printf("%d\n",ans);
}
return ;
15nb0 }

无敌zyd的优化建图,思路是每个i都只与后面有可能构成最优解的j连边,最坏情况下没有任何改进,但好像因为a[i]是随机数据跑的飞快

 #pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(i,l,r) for(int i=l;i<=r;++i)
#define per(i,l,r) for(int i=l;i>=r;--i)
using namespace std; const int N = , M=;
const int INF = 1e9;
int n,m;
int a[M]; struct EG {
int a, b, c, d, e;
} eg[M];
int head[N], en, S, T, SS;
int flow, cost;
int dis[N], pre[N], rem[N];
bool inq[N];
void insert(int u, int v, int w, int z) {
eg[++en] = (EG) {v, head[u], w, z, u}; head[u] = en;
eg[++en] = (EG) {u, head[v], , -z, v}; head[v] = en;
}
void Clear() {
memset(head, , sizeof head);
en = ;
}
bool Spfa() {
for (int i = ; i <= SS; i++) dis[i] = INF, inq[i] = ;
dis[S] = ;
inq[S] = ;
queue<int> Q; Q.push(S);
pre[S] = , rem[S] = INF;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
inq[u] = ;
for (int e = head[u]; e; e = eg[e].b) {
int v = eg[e].a;
if (eg[e].c > && dis[u] + eg[e].d < dis[v]) {
dis[v] = dis[u] + eg[e].d;
pre[v] = e;
rem[v] = min(rem[u], eg[e].c);
if (!inq[v]) {
inq[v] = ;
Q.push(v);
}
}
}
}
if (dis[T] == INF) return ;
flow += rem[T];
cost += dis[T] * rem[T];
int u = T;
while (u != S) {
eg[pre[u]].c -= rem[T];
eg[pre[u] ^ ].c += rem[T];
u = eg[pre[u]].e;
}
return ;
}
void MinCost() {
flow = cost = ;
while (Spfa());
} int main() {
//freopen("a.txt","r",stdin); int test_;
cin>>test_;
while (test_--) {
scanf("%d%d",&n,&m);
rep(i,,n) scanf("%d",a+i); Clear();
S = n * + , T = S + , SS = T + ;
for (int i = ; i <= n; i++)
{
insert(i, i + n, , -a[i]);
insert(i, i + n, m, );
int mx = INF;
for (int j = i + ; j <= n; j++)
{
if (a[j] < mx && a[j] >= a[i])
{
insert(i + n, j, INF, );
mx = a[j];
}
}
}
insert(S, SS, m, );
for (int i = ; i <= n; i++)
{
insert(SS, i, , );
insert(i + n, T, , );
}
MinCost();
printf("%d\n", -cost);
}
}

【HDOJ6611】K Subsequence(费用流)的更多相关文章

  1. POJ - 2516 Minimum Cost 每次要跑K次费用流

    传送门:poj.org/problem?id=2516 题意: 有m个仓库,n个买家,k个商品,每个仓库运送不同商品到不同买家的路费是不同的.问为了满足不同买家的订单的最小的花费. 思路: 设立一个源 ...

  2. poj-2516.minimum cost(k次费用流)

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 19883   Accepted: 7055 Des ...

  3. BZOJ 3836 Codeforces 280D k-Maximum Subsequence Sum (模拟费用流、线段树)

    题目链接 (BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=3836 (Codeforces) http://codeforces.com ...

  4. POJ 2516 Minimum Cost (费用流)

    题面 Dearboy, a goods victualer, now comes to a big problem, and he needs your help. In his sale area ...

  5. BZOJ 1834 [ZJOI2010]network 网络扩容(费用流)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1834 [题目大意] 给定一张有向图,每条边都有一个容量C和一个扩容费用W. 这里扩容费 ...

  6. 补 第三场多校杭电 费用流 K Subsequence

    K Subsequence 这个题目是这个人想吃东西,但是他每次吃的都是他的美味值都必须不递减,可以吃k次,问这个最大的美味值是多少. 这个是一个比较明显的费用流,建图也很好建,但是呢,这个题目卡sp ...

  7. 2019HDU多校第三场 K subsequence——最小费用最大流

    题意 给定一个 $n$ 个整数的数列,从中至多选取 $k$ 个上升子序列(一个元素最多被选一次),使得选取的元素和最大. 分析 考虑这个问题和经典网络流问题“最长不下降子序列”相似,我们考虑对这个建图 ...

  8. HDU 6611 K Subsequence(Dijkstra优化费用流 模板)题解

    题意: 有\(n\)个数\(a_1\cdots a_n\),现要你给出\(k\)个不相交的非降子序列,使得和最大. 思路: 费用流建图,每个点拆点,费用为\(-a[i]\),然后和源点连边,和后面非降 ...

  9. 【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广

    3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 174  Solved: 9 ...

随机推荐

  1. Sparse PCA: reproduction of the synthetic example

    The paper: Hui Zou, Trevor Hastie, and Robert Tibshirani, Sparse Principal Component Analysis, Journ ...

  2. python之环境变量(测试环境可配置)

    想要实现的结果是: 执行脚本时,带一个参数,由这个参数来决定测试环境(开发or测试),比如: python test.py dev 实现代码: 方式1 不用__getitem__方式: import ...

  3. MSSQL sql常用判断语句

    .判断数据库是否存在 if exists (select * from sys.databases where name = '数据库名')    drop database [数据库名]  2 判断 ...

  4. SVG绘制多个圆

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Java thread(2)

    这一块主要是从Thread类源码的角度来分析两种线程的实现方式,这里分析的也仅仅是最基本的部分. 就从线程的启动函数 start方法开始分析 只是分析最主要的部分 在start()方法中,除了grou ...

  6. vs2010修改的内容在浏览器页面不变怎么办

    解决方法1: 如果是静态页面, Ctrl+F5 强制刷新浏览器页面 解决方法2: 页面中<%@ Page Language="C#" CodeBehind="Def ...

  7. Java实现红黑树

    转自:http://www.cnblogs.com/skywang12345/p/3624343.html 红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉 ...

  8. [Linux] 009 链接命令

    链接命令:ln 命令名称:ln 命令英文原意:link 命令所在路径:/bin/ln 执行权限:所有用户 语法:ln -s [原文件] [目标文件] 功能描述:生成链接文件 范例: 创建文件 /etc ...

  9. Python自学第二天学习之《字符串与数字》

    一.基本数据类型: 数字:int类型,不可变类型 格式 : a=10 1.其他类型转换成int型 : b=“123” c=int(b) #转换类型 print(c)----- 123 print(ty ...

  10. hdu1394 Minimum Inversion Number (线段树求逆序数&&思维)

    题目传送门 Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...