#include #include #include #include #include #include #include #include #include #include using namespace std; int workTime; const int MAXN = 105; struct state { int dogs, index; long long score; }; struct dog { int grid = 0; string way = ""; pair start; bool changed = false; }; struct cat { int value; pair position; }; cat A; priority_queue Q; int k, f; char a[105][MAXN][MAXN]; int prize[105], n[105], m[105]; int dist[MAXN][MAXN]; queue q; queue < pair > BFSq; bool usedCat[10005]; vector < pair > cats[105]; bool used[105][105]; int memo[505][105]; int predecessor[505][105]; bool calculated[505][105], calculatedStates[505][105]; dog action[505], action1[505]; int add; int precompute[505][105]; bool mode; bool operator<(const state A, const state B) { if(A.dogs!=B.dogs) return A.dogs BFS(pair x, int index) { pair answer; memset(dist, false, sizeof(dist)); while(BFSq.empty()==false) BFSq.pop(); BFSq.push(x); dist[x.first][x.second] = 1; answer.first = -1; while(BFSq.empty()==false) { x = BFSq.front();BFSq.pop(); //cout << x.first << " " << x.second << " ---> " << dist[x.first][x.second] << '\n'; //cout << used[x.first][x.second] << " " << answer.first << " " << dist[x.first][x.second] << '\n'; if(used[x.first][x.second]==false && answer.first==-1 && dist[x.first][x.second]>1 && a[index][x.first][x.second]!='.' && a[index][x.first][x.second]!='#') { answer = make_pair(x.first, x.second); dist2Nearest = dist[x.first][x.second]; //cout << "Ok " << answer << '\n'; if(mode==false) return answer; } //if(a[index][x.first][x.second]!='.' && a[index][x.first][x.second]!='#') continue; if(x.first-1>0 && a[index][x.first-1][x.second]!='#' && dist[x.first-1][x.second]==0) { dist[x.first-1][x.second] = dist[x.first][x.second] + 1; BFSq.push(make_pair(x.first-1, x.second)); } if(x.first+1<=n[index] && a[index][x.first+1][x.second]!='#' && dist[x.first+1][x.second]==0) { dist[x.first+1][x.second] = dist[x.first][x.second] + 1; BFSq.push(make_pair(x.first+1, x.second)); } if(x.second-1>0 && a[index][x.first][x.second-1]!='#' && dist[x.first][x.second-1]==0) { dist[x.first][x.second-1] = dist[x.first][x.second] + 1; BFSq.push(make_pair(x.first, x.second-1)); } if(x.second+1<=m[index] && a[index][x.first][x.second+1]!='#' && dist[x.first][x.second+1]==0) { dist[x.first][x.second+1] = dist[x.first][x.second] + 1; BFSq.push(make_pair(x.first, x.second+1)); } } return answer; } string generateWay(pair x, int index) { string answer = ""; int i = x.first; int j = x.second; while(dist[i][j]!=1) { if(i-1>0 && dist[i-1][j]+1==dist[i][j]) {i--;answer += "D";} else if(i+1<=n[index] && dist[i+1][j]+1==dist[i][j]) {i++;answer += "U";} else if(j-1>=0 && dist[i][j-1]+1==dist[i][j]) {j--;answer += "R";} else if(j+1<=m[index] && dist[i][j+1]+1==dist[i][j]) {j++;answer += "L";} } reverse(answer.begin(), answer.end()); return answer; } int initialDogs; vector < pair > copyCats; int useDogs(int dogs, int index) { int startDogs = dogs, reached; if(dogs==0) return 0; int start = clock(); int limit = cats[index].size()/dogs, catsByDog; if(limit==0) limit = 1; bool outOfTime = false; long long score, answer = 0, w; copyCats = cats[index]; if(n[index]*m[index]<=1005) add = 1; else if(n[index]*m[index]>=3000) add = sqrt(limit); else add = limit/15; if(add==0) add++; pair x; for(int c = (limit);c<=limit;c+=add) { if(clock()-start>=workTime) break; if(outOfTime==true) break; for(int style = 0;style<1;style++) { if(clock()>=((mode==true)?4900:((f>=2 && f<=100)?4550:3600))) break; while(Q.empty()==false) Q.pop(); for(int i = 0;i=workTime) break; while(Q.empty()==false && used[ Q.top().position.first ][ Q.top().position.first ]==true) Q.pop(); if(Q.empty()==true) break; x = Q.top().position;Q.pop(); if(dogs==0) break; if(used[ x.first ][ x.second ]==false) { dogs--;score += a[index][ x.first ][ x.second ] - '0';; if(dogs==0 && startDogs=((mode==true)?4900:((f>=2 && f<=100)?4550:3600))) break; reached++; toDo = false; //cout << x.first << " " << x.second << " || " << a[index][ x.first ][ x.second ] - '0' << " -> " << '\n'; //usedCat[i1] = true; used[ x.first ][ x.second ] = true; x = BFS(x, index); if(x.first==-1 || j==catsByDog-1) break; //cout << x.first << " " << x.second << " - " << dist[ x.first ][ x.second ] << "\n"; /* i1++; if(i1>=cats[index].size() || i1>=i+catsByDog) break; */ /* i1 = findNearest(index); if(i1==-1) break; */ if(mode==true) { action1[k-(initialDogs-dogs)].way += generateWay(x, index); if(action1[k-dogs-1].way.size()>=19505) break; } toDo = true; w += dist2Nearest - 1; score += a[index][ x.first ][ x.second ] - '0'; } if(x.first!=-1 && toDo==true) { //usedCat[i1] = true; used[ x.first ][ x.second ] = true; } } } //if(c==4 && style==0) cout << score << " " << w << '\n'; score = 2*score - w + ((reached==cats[index].size())?prize[index]:0); //if(score==97) {cout << c << " " << style << " - " << w << " " << catsByDog << " " << t << '\n';exit(0);} if(answer x; do { for(int c = (limit);c<=limit;c+=add) { if(clock()-start>=workTime) break; if(outOfTime==true) break; for(int style = 0;style<1;style++) { if(clock()>=((mode==true)?4900:((f>=2 && f<=100)?4550:3600))) break; if(mode==true) { for(int i = 0;i=((mode==true)?4900:((f>=2 && f<=100)?4550:3600))) break; reached++; toDo = false; //cout << x.first << " " << x.second << " || " << a[index][ x.first ][ x.second ] - '0' << " -> " << '\n'; //usedCat[i1] = true; used[ x.first ][ x.second ] = true; x = BFS(x, index); if(x.first==-1 || j==catsByDog-1) break; //cout << x.first << " " << x.second << " - " << dist[ x.first ][ x.second ] << "\n"; /* i1++; if(i1>=cats[index].size() || i1>=i+catsByDog) break; /* i1 = findNearest(index); if(i1==-1) break; */ if(mode==true) { action1[k-(initialDogs-dogs)].way += generateWay(x, index); if(action1[k-dogs-1].way.size()>=19505) break; } toDo = true; w += dist2Nearest - 1; score += a[index][ x.first ][ x.second ] - '0'; } if(x.first!=-1 && toDo==true) { //usedCat[i1] = true; used[ x.first ][ x.second ] = true; } } } //if(c==4 && style==0) cout << score << " " << w << '\n'; score = 2*score - w + ((reached==cats[index].size())?prize[index]:0); //if(score==97) {cout << c << " " << style << " - " << w << " " << catsByDog << " " << t << '\n';exit(0);} if(answer x; bool toDo; int r; for(int r = 0;r<30;r++) { if(clock()-start>=workTime) break; if(clock()>=((mode==true)?4900:((f>=2 && f<=100)?4550:3600))) break; for(int c = (limit);c<=limit;c+=add) { if(clock()-start>=workTime) break; if(outOfTime==true) break; for(int style = 0;style<1;style++) { if(clock()>=((mode==true)?4900:((f>=2 && f<=100)?4550:3600))) break; if(mode==true) { for(int i = 0;i=((mode==true)?4900:((f>=2 && f<=100)?4550:3600))) break; reached++; toDo = false; //cout << x.first << " " << x.second << " || " << a[index][ x.first ][ x.second ] - '0' << " -> " << '\n'; //usedCat[i1] = true; used[ x.first ][ x.second ] = true; x = BFS(x, index); if(x.first==-1 || j==catsByDog-1) break; //cout << x.first << " " << x.second << " - " << dist[ x.first ][ x.second ] << "\n"; /* i1++; if(i1>=cats[index].size() || i1>=i+catsByDog) break; /* i1 = findNearest(index); if(i1==-1) break; */ if(mode==true) { action1[k-(initialDogs-dogs)].way += generateWay(x, index); if(action1[k-dogs-1].way.size()>=19505) break; } toDo = true; w += dist2Nearest - 1; score += a[index][ x.first ][ x.second ] - '0'; } if(x.first!=-1 && toDo==true) { //usedCat[i1] = true; used[ x.first ][ x.second ] = true; } } } //if(c==4 && style==0) cout << score << " " << w << '\n'; score = 2*score - w + ((reached==cats[index].size())?prize[index]:0); //if(score==83) {cout << c << " " << style << " - " << w << " " << catsByDog << '\n';exit(0);} if(answer " << score << '\n'; if(index==f) return score; if(calculated[dogs][index]==true) return memo[dogs][index] + score; int maxScore = 0, pred, current; for(int i = 0;i<=dogs;i++) { if(clock()>=((f>=2 && f<=100)?4550:3600)) { memo[dogs][index] = maxScore - score; predecessor[dogs][index] = pred; return maxScore; } if(i>cats[index].size()) break; if(calculatedStates[i][index]==false) { calculatedStates[i][index] = true; precompute[i][index] = useDogs(i, index); } current = calcSate(dogs-i, index+1, score+precompute[i][index]); if(current>maxScore) { maxScore = current; pred = i; } } memo[dogs][index] = maxScore - score; predecessor[dogs][index] = pred; calculated[dogs][index] = true; return maxScore; } int main() { int start, stop; long long answer = 0;; ifstream cin("catsdogs.in"); ofstream cout("catsdogs.out"); start = clock(); cin >> f >> k; for(int t = 0;t> n[t] >> m[t] >> prize[t]; cin.get(); for(int i = 1;i<=n[t];i++) { for(int j = 1;j<=m[t];j++) cin.get(a[t][i][j]); cin.get(); } for(int i = 1;i<=n[t];i++) { for(int j = 1;j<=m[t];j++) { if(a[t][i][j]!='.' && a[t][i][j]!='#') { cats[t].push_back(make_pair(i, j)); } } } } if(k==1) workTime = 3700/f; else if(f<=1) workTime = 3700/k; else if(f<=50) workTime = 125; else workTime = 65; calcSate(k, 0, 0); mode = true; int dogs = k, index = 0; for(int i = 0;i