题意:
标程:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=205; 4 const int inf=0x3f3f3f3f; 5 struct node{int to,next,w,c;}num[N*10]; 6 queue<int> q; 7 int cnt=1,sc,S,T,dis[N],head[N],n,a[N],c[N],ans,k,pre[N],prevv[N],preve[N],t[1000005]; 8 void add(int x,int y,int w,int c) 9 {num[++cnt].to=y;num[cnt].next=head[x];num[cnt].w=w;num[cnt].c=c;head[x]=cnt; 10 num[++cnt].to=x;num[cnt].next=head[y];num[cnt].w=-w;num[cnt].c=0;head[y]=cnt;} 11 12 void build() 13 { 14 for (int i=1;i<n;i++) add(i,i+1,0,k-1); 15 for (int i=1;i<=n;i++) 16 if (pre[i]&&pre[i]!=i-1) 17 { 18 add(S,pre[i]+1,0,1); 19 add(pre[i]+1,++sc,0,1); 20 add(i,sc,-c[a[i]],1); 21 add(sc,T,0,1); 22 } 23 } 24 void spfa() 25 { 26 q.push(S);memset(dis,inf,sizeof(dis)); 27 dis[S]=0; 28 while (!q.empty()) 29 { 30 int now=q.front();q.pop(); 31 for (int i=head[now];i;i=num[i].next) 32 if (num[i].c&&dis[num[i].to]>dis[now]+num[i].w) 33 { 34 dis[num[i].to]=dis[now]+num[i].w,q.push(num[i].to); 35 prevv[num[i].to]=now;preve[num[i].to]=i; 36 } 37 38 } 39 } 40 void solve() 41 { 42 while (1==1) 43 { 44 spfa(); 45 if (dis[T]==inf) break; 46 int sum=0; 47 for (int i=T,it;i!=S;i=prevv[i]) 48 it=preve[i],sum+=num[it].w,num[it].c--,num[it^1].c++; 49 ans+=sum; 50 } 51 } 52 int main() 53 { 54 scanf("%d%d",&n,&k); 55 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 56 for (int i=1;i<=n;i++) scanf("%d",&c[i]); 57 for (int i=1;i<=n;i++) 58 { 59 pre[i]=t[a[i]];t[a[i]]=i; 60 if (i==1||pre[i]!=i-1) ans+=c[a[i]]; 61 } 62 S=n+1;T=sc=S+1; 63 build();solve(); 64 printf("%d\n",ans); 65 return 0; 66 }
题解:最小费用最大流