#include #include #include #include #include #include #include using namespace std; #define REP(i,n) for(int (i)=0;(i)<(n);(i)++) #define REPD(i,n) for(int (i)=(n)-1;(i)>=0;(i)--) #define FOR(i,s,n) for(int (i)=(s);(i)<(n);(i)++) #define VI vector #define VS vector #define VB vector #define PB push_back #define LL long long long double START; long double get_time() { return (long double)clock()/CLOCKS_PER_SEC; } int fsb[105]; int FS[105]; int F,K; int B[105]; int N[105]; int M[105]; VS fields[105]; bool ok(int i,int j,const VS &grid) { return i>=0 && j>=0 && i0 && val<=9) { sv[ns]=val; si[ns]=i; sj[ns]=j; ns++; } REP(k,4) { int ni=i+di[k]; int nj=j+dj[k]; if(ok(ni,nj,grid)&&!vis[ni][nj]&&grid[ni][nj]!='#')dfs(ni,nj,grid); } } bool qseen[105][105]; int qprev[10005]; int qi[10005]; int qj[10005]; int qt,qh; int ncs; bool catsseen[105][105]; int seecatid; char path[20005]; int pathId; void get_path(int id,VS &grid) { int onsq = grid[qi[id]][qj[id]]-'0'; if(onsq>0 && onsq<10)catsseen[qi[id]][qj[id]]=true; int pid = qprev[id]; char to; if(pid<0)return; else { int dli = qi[id]-qi[pid]; int dlj = qj[id]-qj[pid]; if(dli!=0) {if(dli==-1)to = 'U';else to = 'D';} else {if(dlj==-1) to = 'L';else to = 'R';} get_path(pid,grid); if(pathId>20000)pathId=20000; path[pathId++]=to; } } inline bool iscat(char v) { return v>='0' && v<='9'; } //dummy reach cats function void bfs(int i,int j,int goalcat, VS& grid) { ncs = ns,qt=0,qh=0; qi[qt]=i;qj[qt]=j;qprev[qt]=-1;qt++;qseen[i][j]=true; int gi=si[goalcat],gj=sj[goalcat]; //printf("BFS from %d %d, searching for %d %d\n",i,j,gi,gj); while(qhb.val;} struct seg { int i,j,val,f; string path; double bval; }; bool operator<(const seg& a,const seg& b) {return a.val+a.bval>b.val+b.bval;} vector cats; vector segs; LL score(VI &conf) { memset(fsb,0,sizeof(fsb)); LL res=0; int n=K; if(K>segs.size())n=segs.size(); REP(i,n) { res+=segs[conf[i]].val; //printf("Steps bonus %d\n",res); } REP(i,n) { int fid = segs[conf[i]].f; //printf("NEED %d for f[%d]\n",FS[fid],fid); fsb[fid]++; if(fsb[fid]==FS[fid])res+=B[fid]; } //printf("Field bonus %d\n",res); return res; } int main() { #ifndef LOCALZ freopen ("catsdogs.out","w",stdout); #else START = get_time(); #endif srand(2017); freopen ("catsdogs.in","r",stdin); scanf("%d %d",&F,&K); char buf[105]; int endseg = 0; REP(f,F) { scanf("%d %d %d",&N[f],&M[f],&B[f]); REP(i,N[f]) { scanf("%s",buf); string a(buf); fields[f].PB(a); REP(j,M[f])if(a[j]>='0' && a[j]<='9'){ cat c;c.val=a[j]-'0';c.f=f;c.i=i;c.j=j;cats.PB(c); } } memset(vis,false,sizeof(vis)); memset(qseen,false,sizeof(qseen)); memset(catsseen,false,sizeof(catsseen)); ns=0; int startseg = endseg; REP(i,N[f]) REP(j,M[f]) { if(!vis[i][j] && fields[f][i][j]!='#') { //printf("new ff\n"); ns=0; pathId=0; dfs(i,j,fields[f]); if(ns==0)continue; //REP(k,ns)printf("saw cat %d %d %d\n",sv[k],si[k],sj[k]); int curcatid=0; int nextcatid=1; while(nextcatid20000)pathId=20000; seg s; s.i=si[0];s.j=sj[0];s.f=f; s.val=0;REP(cid,ns)s.val+=fields[f][si[cid]][sj[cid]]-'0'; s.val=s.val*2-pathId; string pt(path,pathId); if(pathId==0)pt="STAY"; s.path = pt; segs.PB(s); endseg++; //printf("PATH %s %d\n",path,s.val); } } int numsegs = endseg-startseg; if(numsegs>0) { FS[f]=numsegs; double bval = (double)B[f]/(double)numsegs; FOR(ii,startseg,endseg)segs[ii].bval=bval; //printf("BVAL %d %f\n",f,bval); } } //sort(cats.begin(),cats.end()); LL bestscore = -1000000000; VI best; VI cur; VI shuff; REP(bi,segs.size())best.PB(bi); REP(bi,segs.size())cur.PB(bi); REP(bi,segs.size())shuff.PB(bi); sort(segs.begin(),segs.end()); bestscore = score(best); //printf("SCORE IS %d\n",score(best)); int i=0; do { i++; LL tscore = score(cur); if(tscore>bestscore) { bestscore=tscore; REP(j,cur.size())best[j]=cur[j]; } random_shuffle(shuff.begin(),shuff.end()); tscore = score(shuff); if(tscore>bestscore) { bestscore=tscore; REP(j,shuff.size())best[j]=shuff[j]; } if(i%10==0 && get_time()-START>4.0)break; } while(next_permutation(cur.begin(),cur.end())); REP(kk,K) { if(kk