Topic links: codeforces - Minimum path
The minimum lexicographical obviously be greedy.
We first find the chance to use k, x + y is the maximum position, obviously greedy. There are probably many points, how to get it?
We determine the current point of all the points, which is then stored into the vector, sorted according to the lexicographic order. Because greed rule, equal to only go until the first character, and a point will only be updated once.
So go and sort of violence can be.
AC Code:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e3+10;
int n,k,sum[N][N],mx,vis[N][N];
char g[N][N]; pair<int,int> pre[N][N];
vector<pair<int,int> > v;
struct node{int x,y,p;}; vector<node> q;
int cmp(node a,node b){return a.p<b.p;}
signed main(){
cin>>n>>k;
for(int i=1;i<=n;i++) scanf("%s",g[i]+1);
if(k&&g[1][1]!='a') k--,g[1][1]='a';
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
sum[i][j]=max(sum[i-1][j],sum[i][j-1])+(g[i][j]=='a');
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) if(i+j-1<=sum[i][j]+k&&i+j>=mx){
if(i+j>mx) v.clear(),v.push_back({i,j}),mx=i+j;
else v.push_back({i,j});
}
}
if(v.size()==0) v.push_back({1,1}),cout<<g[1][1];
for(int i=0;i<v.size();i++){
int x=v[i].first,y=v[i].second;
if(x+1<=n&&!vis[x+1][y])
vis[x+1][y]=1,pre[x+1][y]={x,y},q.push_back({x+1,y,(int)g[x+1][y]});
if(y+1<=n&&!vis[x][y+1])
vis[x][y+1]=1,pre[x][y+1]={x,y},q.push_back({x,y+1,(int)g[x][y+1]});
}
while(q.size()){
sort(q.begin(),q.end(),cmp);
int x=q[0].x,y=q[0].y; vector<node> t;
if(x+1<=n&&!vis[x+1][y])
vis[x+1][y]=1,pre[x+1][y]={x,y},t.push_back({x+1,y,(int)g[x+1][y]});
if(y+1<=n&&!vis[x][y+1])
vis[x][y+1]=1,pre[x][y+1]={x,y},t.push_back({x,y+1,(int)g[x][y+1]});
for(int i=1;i<q.size();i++){
if(q[i].p>q[i-1].p) break;
x=q[i].x,y=q[i].y;
if(x+1<=n&&!vis[x+1][y])
vis[x+1][y]=1,pre[x+1][y]={x,y},t.push_back({x+1,y,(int)g[x+1][y]});
if(y+1<=n&&!vis[x][y+1])
vis[x][y+1]=1,pre[x][y+1]={x,y},t.push_back({x,y+1,(int)g[x][y+1]});
}
q.clear();
for(int i=0;i<t.size();i++) q.push_back(t[i]);
t.clear();
}
for(int i=1;i<mx;i++) putchar('a');
stack<char> res; int x=n,y=n;
while(x!=0){
int tx=x,ty=y;
res.push(g[x][y]); x=pre[tx][ty].first,y=pre[tx][ty].second;
}
res.pop();
while(res.size()) cout<<res.top(),res.pop();
return 0;
}