BZOJ 1283 序列 费用流 网络流 线性规划
https://darkbzoj.cf/problem/1283
给出一个长度为N的正整数序列Ci,求一个子序列,使得原序列中任意长度为M的子串中被选出的元素不超过K(K,M<=100) 个,并且选出的元素之和最大。
http://www.cnblogs.com/137shoebills/p/8871648.html
↑和这道题一样
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=1100; 9 int n,m,k,S,T,SS; 10 struct nod{ 11 int x,y,v,co,rev,next; 12 }e[10*maxn]; 13 int head[maxn]={},tot=0; 14 int a[maxn]={}; 15 void init(int x,int y,int v,int co){ 16 e[++tot].x=x;e[tot].y=y;e[tot].v=v;e[tot].co=co;e[tot].rev=tot+1;e[tot].next=head[x];head[x]=tot; 17 e[++tot].x=y;e[tot].y=x;e[tot].v=0;e[tot].co=-co;e[tot].rev=tot-1;e[tot].next=head[y];head[y]=tot; 18 } 19 queue<int>q; 20 int vis[maxn]={},fa[maxn]={},dis[maxn]={}; 21 bool SPFA(){ 22 memset(dis,31,sizeof(dis)); 23 memset(vis,0,sizeof(vis)); 24 memset(fa,0,sizeof(fa)); 25 q.push(S);vis[S]=1;dis[S]=0; 26 while(!q.empty()){ 27 int x=q.front();q.pop();vis[x]=0; 28 for(int i=head[x];i;i=e[i].next){ 29 if(!e[i].v)continue; 30 if(dis[e[i].y]>dis[x]+e[i].co){ 31 dis[e[i].y]=dis[x]+e[i].co; 32 fa[e[i].y]=i; 33 if(!vis[e[i].y]){ 34 q.push(e[i].y);vis[e[i].y]=1; 35 } 36 } 37 } 38 } 39 return fa[T]; 40 } 41 int doit(){ 42 int val=maxn,ans=0; 43 for(int i=fa[T];i;i=fa[e[i].x])val=min(val,e[i].v); 44 for(int i=fa[T];i;i=fa[e[i].x]){ 45 e[i].v-=val;e[e[i].rev].v+=val;ans+=e[i].co; 46 } 47 return ans; 48 } 49 int main(){ 50 scanf("%d%d%d",&n,&m,&k); 51 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 52 T=n+1;S=T+1;SS=S+1; 53 for(int i=1;i<=n;i++){ 54 init(i,i+m>n?T:i+m,1,-a[i]); 55 init(i,i+1>n?T:i+1,k,0); 56 } 57 for(int i=1;i<=m;i++)init(SS,i,maxn,0); 58 init(S,SS,k,0); 59 int ans=0; 60 while(SPFA())ans-=doit(); 61 printf("%d\n",ans); 62 return 0; 63 }