Title (Original is Japanese):
In the Google Code Jam area, the man in front of the right is called lyrically. In the memory of the University of Tokyo, remember that a friend also uses a similar ID. But my friends are the sister, I remember the lyrically not only the algorithm solid, packaging is also very strong, can suddenly give the problem of positive solution. For example, programs that are poorly written to us can also be tuned to the level of AC. She says the use of the cache pool is particularly important when optimizing programs.
So here's the problem, now please optimize the following cache pool model:
There are m barrels, n balls, the ball is numbered 1 to N, each ball has a weight of w_i. Then give a long k of the series, the number of the ball is composed of numbers. At first, the buckets were empty. We then take a number a_j from the sequence after we go, doing the following:
If the ball a_j already exists in a bucket, then nothing is done and it costs 0 to continue.
If there is no a_j in any bucket, then find a bucket to put a_j, if there is a ball in the bucket, then take out the original ball, put A_j in. The cost of this operation is a_j the weight of the W_a_j, which does not matter with the barrel and the original ball.
Minimum cost?
The first line of the title data is M n K, then the N line weights, and the K line number.
Idea: First of all, this is the "Challenge program Design" part of the cost flow exercises. Then we should consider the direction of the cost flow. When we use the bucket, every time there must be a bucket to be used to install a new ball, that is, the bucket is not a reserved bucket, while the other barrels can be empty barrels, can also be loaded with things. The previous ball may be used later to reduce the cost. Then we just need to consider the most effective way to save how much money. At the same time a maximum of m-1 bucket is reserved, how long? Keep to the next time you encounter the same ball. If you choose to keep this bucket, the bucket is not available in this range. Think about it, this is not the book's example of the maximum weight range selection! (POJ 3680). So the question is, how to choose the most m-1 intersection interval, so that the weights and maximum.
Title translation from: http://www.hankcs.com/program/algorithm/aoj-2266-cache-strategy.html
/** @author: Cwind*////#pragma COMMENT (linker, "/stack:102400000,102400000")#include <iostream>#include<map>#include<algorithm>#include<cstdio>#include<cstring>#include<cstdlib>#include<vector>#include<queue>#include<stack>#include<functional>#include<Set>#include<cmath>using namespacestd;#definePB Push_back#definePB Pop_back#defineBK Back ()#defineFS First#defineSe Second#defineSq (x) (x) * (x)#defineEPS (1E-10)#defineINF (1000000300)#defineCLR (x) memset ((x), 0,sizeof (x))#defineCP (A, a) memcpy ((a), (b), sizeof (b))typedefLong Longll;typedef unsignedLong LongUll;typedef pair<int,int>P;typedef pair<ll,int>D;Const intmaxv=1e4+ -;intV;Const ints=maxv-1, t=maxv-2;structedge{intTo,cap,cost,next;} ES[MAXV*Ten];inteh;intH[MAXV];intDIS[MAXV];intPREVV[MAXV],PREVE[MAXV];intHEAD[MAXV];voidAddedge (int from,intTo,intCapintCost ) {es[eh].to=to;es[eh].cap=cap;es[eh].cost=Cost ; Es[eh].next=head[ from];head[ from]=eh++; Es[eh].to= from; es[eh].cap=0; es[eh].cost=-Cost ; Es[eh].next=head[to];head[to]=eh++;}BOOLinq[maxv];ll Min_cost_flow (intSintTintf) {V=MAXV;//default V size maxedll res=0; memset (H,0,sizeofh); Queue<P> Q;////SPFA Computing Potential HFill (dis,dis+V,inf); Dis[s]=0; Q.push (P (0, s)); Inq[s]=1; while(!Q.empty ()) {p P=Q.front (); Q.pop (); intv=p.se; INQ[V]=0; for(inti=head[v];i!=-1; i=Es[i].next) {EDGE&e=Es[i]; if(e.cap>0&&dis[e.to]>dis[v]+e.cost+h[v]-H[e.to]) {Dis[e.to]=dis[v]+e.cost +h[v]-H[e.to]; Prevv[e.to]=v; Preve[e.to]=i; if(!inq[e.to]) Q.push (P (dis[e.to],e.to)), inq[e.to]=1; } } } for(intv=0; v<v;v++) H[v]+=Dis[v]; while(f>0) {priority_queue<P,vector<P>,greater<p> >Q;////dijkstra Computing Potential HFill (dis,dis+V,inf); Dis[s]=0; Q.push (P (0, s)); while(!Q.empty ()) {p P=Q.top (); Q.pop (); intv=p.se; if(DIS[V]<P.FS)Continue; for(inti=head[v];i!=-1; i=Es[i].next) {EDGE&e=Es[i]; if(e.cap>0&&dis[e.to]>dis[v]+e.cost+h[v]-H[e.to]) {Dis[e.to]=dis[v]+e.cost +h[v]-H[e.to]; Prevv[e.to]=v; Preve[e.to]=i; Q.push (P (dis[e.to],e.to)); } } } if(Dis[t]==inf)return-1; for(intv=0; v<v;v++) h[v]+=Dis[v]; intD=F; for(intv=t;v!=s;v=Prevv[v]) d=min (d,es[preve[v]].cap); F-=D; Res+=d*H[t]; for(intv=t;v!=s;v=Prevv[v]) {EDGE&e=Es[preve[v]]; E.cap-=D; ES[PREVE[V]^1].cap+=D; } } returnRes;}voidclear_g () {EH=0; memset (Head,-1,sizeofhead);}Const intmaxn=1e4+ -;intm,n,k;intA[MAXN],W[MAXN];intLAST[MAXN];intTol;inthh;voidbuild () { for(intI=1; i) {tol+=W[a[i]]; if(Last[a[i]]) Addedge (last[a[i]],i-1,1,-W[a[i]]); Last[a[i]]=i; } for(intI=1; i1; i++) Addedge (i,i+1Inf0);}intMain () {Freopen ("/home/slyfc/cppfiles/in","R", stdin); //freopen ("/home/slyfc/cppfiles/out", "w", stdout);Clear_g (); CIN>>M>>N>>J; for(intI=1; i<=n;i++) scanf ("%d",&W[i]); for(intI=1; i<=k;i++) scanf ("%d",&A[i]); HH=unique (A +1, a+k+1)-A; Build (); intAns=min_cost_flow (1, hh-1, M-1); cout<<tol+ans<<Endl; return 0; }
View Code
Aizu Aoj 2266 (fee flow