Codeforces - Minimum path

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;
}
Published 477 original articles · won praise 241 · views 20000 +

Guess you like

Origin blog.csdn.net/weixin_43826249/article/details/104095377