题意:给定一个长为n的正整数序列,要求从中取出至多k个不下降序列,使得它们的和最大,求这个和
n<=2e3,k<=10,a[i]<=1e5
思路:极其考验模板,反正我的spfa和zkw都挂了,就拿这题std做dijkstra费用流的板子了
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,ll>P; 11 #define N 10000 12 #define M 2100000 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pb push_back 17 #define pi acos(-1) 18 #define mem(a,b) memset(a,b,sizeof(a)) 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 21 #define lowbit(x) x&(-x) 22 #define Rand (rand()*(1<<16)+rand()) 23 #define id(x) ((x)<=B?(x):m-n/(x)+1) 24 #define ls p<<1 25 #define rs p<<1|1 26 27 const int MOD=998244353,inv2=(MOD+1)/2; 28 double eps=1e-4; 29 int INF=0x7fffffff;; 30 ll inf=5e13; 31 int dx[4]={-1,1,0,0}; 32 int dy[4]={0,0,-1,1}; 33 34 struct edge 35 { 36 int to,cap,cost,rev; 37 edge(){} 38 edge(int a,int b,int c,int d): 39 to(a),cap(b),cost(c),rev(d){} 40 }; 41 42 int read() 43 { 44 int v=0,f=1; 45 char c=getchar(); 46 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 47 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 48 return v*f; 49 } 50 51 struct MCMF 52 { 53 int V,h[N],dis[N],preV[N],preE[N]; 54 vector<edge> g[N]; 55 56 void init(int n) 57 { 58 V=n; 59 rep(i,0,V) g[i].clear(); 60 } 61 62 void add(int u,int v,int cap,int cost) 63 { 64 g[u].pb(edge(v,cap,cost,g[v].size())); 65 g[v].pb(edge(u,0,-cost,g[u].size()-1)); 66 } 67 68 int minc_mf(int S,int T,int f,int &flow) 69 { 70 int res=0; 71 fill(h,h+1+V,0); 72 while(f) 73 { 74 priority_queue <PII,vector<PII>, greater<PII> > q; 75 fill(dis,dis+1+V,INF); 76 dis[S]=0; 77 q.push(MP(0,S)); 78 while(!q.empty()) 79 { 80 PII now=q.top(); q.pop(); 81 int u=now.se; 82 if(dis[u]<now.fi) continue; 83 for(int i=0;i<g[u].size();i++) 84 { 85 edge e=g[u][i]; 86 int v=e.to; 87 if(e.cap>0&&dis[v]>dis[u]+e.cost+h[u]-h[v]) 88 { 89 dis[v]=dis[u]+e.cost+h[u]-h[v]; 90 preV[v]=u; 91 preE[v]=i; 92 q.push(MP(dis[v],v)); 93 } 94 95 } 96 } 97 if(dis[T]==INF) break; 98 rep(i,0,V) h[i]+=dis[i]; 99 int t=f,k=T; 100 while(k!=S) 101 { 102 int e=preE[k]; 103 t=min(t,g[preV[k]][preE[k]].cap); 104 k=preV[k]; 105 } 106 f-=t; flow+=t; res+=t*h[T]; 107 k=T; 108 while(k!=S) 109 { 110 edge &e=g[preV[k]][preE[k]]; 111 e.cap-=t; 112 g[k][e.rev].cap+=t; 113 k=preV[k]; 114 } 115 } 116 return res; 117 } 118 }mcmf; 119 120 int num[N][2],a[N],S,T,s,flow; 121 122 int main() 123 { 124 int cas=read(); 125 s=0; 126 while(cas--) 127 { 128 int n=read(),k=read(); 129 rep(i,1,n) a[i]=read(); 130 s=0; 131 rep(i,1,n) 132 { 133 num[i][0]=++s; 134 num[i][1]=++s; 135 } 136 S=++s; s++; T=++s; 137 mcmf.init(s); 138 mcmf.add(S,S+1,k,0); 139 rep(i,1,n) mcmf.add(S+1,num[i][0],1,0); 140 rep(i,1,n) mcmf.add(num[i][0],num[i][1],1,-a[i]); 141 rep(i,1,n) 142 rep(j,i+1,n) 143 if(a[j]>=a[i]) mcmf.add(num[i][1],num[j][0],1,0); 144 rep(i,1,n) mcmf.add(num[i][1],T,1,0); 145 flow=0; 146 int ans=-mcmf.minc_mf(S,T,INF,flow); 147 printf("%d\n",ans); 148 } 149 return 0; 150 }