题意:给定一个长为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. English-taxonomy

    域.界.门.纲.目.科.属.种 Domain, Kingdom, Phylum, Class, Order, Family, Genus, Species

  2. rpm --qf 命令

    1. 环境准备: sudo apt-get install rpm (Ubuntu系统) wget ftp://rpmfind.net/linux/fedora-secondary/developme ...

  3. IQueryable不能使用异步方法的解决方案

    ---恢复内容开始--- 看见别人用Linq to Sql的Async好久了,我还没开始用,感觉太土了,跟不上潮流了,打开vs,就准备写个查询,然后发现我用一个IQueryable的对象,怎么都点不出 ...

  4. java c 标签的使用

    头部需要引入: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 需要 ...

  5. ICPC2019上海区域赛 部分题解(正在更新)

    K. Color Graph 题意: 给定一个简单图,点个数<=16,删去部分边后,使得该图中无边数为奇数得环,问剩下的边数最大为多少? 思路: 如果一个图中无奇数边的环,那么这个图一定是个二分 ...

  6. Phone-java标准类

    //project-module-package //.代表包的目录层次 package cn.learn.day01.demo01; /* 1.类是一组相关属性(成员变量)与行为(方法)的集合,对象 ...

  7. jq 与原生js 方法互相转换

    最近在用mui写页面,当然了在移动App里引入jq或zepto这些框架,肯定是极不理性的.虽然jq很简单,但是也有兼容问题,js基础是很重要的,jq的成功当时是因为ie6.7.8.9.10.chrom ...

  8. CentOS tcpdump的使用实例

    tcpdump是一个用于截取网络分组,并输出分组内容的工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为类UNIX系统下用于网络分析和问题排查的首选工具. 选项: -A 以ASCII格式打印 ...

  9. python常用模块----re模块

    正则表达式就是匹配字符串内容的一种规则. 字符组: [0123456789] 表示0-9这个范围内的任意一个数字都可以与之匹配,简写为[0-9] [a-z] 表示匹配所有的小写字母 [A-Z] 表示匹 ...

  10. BFS+打印路径

    题目是给你起点sx,和终点gx:牛在起点可以进行下面两个操作: 步行:John花一分钟由任意点X移动到点X-1或点X+1. 瞬移:John花一分钟由任意点X移动到点2*X. 你要输出最短步数及打印路径 ...