題意
給出一個(n imes n)的矩陣,允許修改(k)次,求一條從((1, 1))到((n, n))的路徑。要求字典序最小
Sol
很顯然的一個思路是對於每個點,預處理出從((1, 1))到該點最多能經過多少個(1)
然後到這裡我就不會做了。。
接下來應該還是比較套路的吧,就是類似於BFS一樣,可以列舉步數,然後再列舉向下走了幾次,有點分層圖的感覺。
/*
*/
#include<bits/stdc++.h>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
//#define int long long
#define LL long long
#define rg register
#define pt(x) printf("%d ", x);
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 2001, INF = 1e9 + 10, mod = 1e9 + 7, B = 1;
const double eps = 1e-9;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < `0` || c > `9`) {if(c == `-`) f = -1; c = getchar();}
while(c >= `0` && c <= `9`) x = x * 10 + c - `0`, c = getchar();
return x * f;
}
int N, K, vis[MAXN][MAXN], f[MAXN][MAXN];
char s[MAXN][MAXN];
int main() {
N = read(); K = read();
for(int i = 1; i <= N; i++) scanf("%s", s[i] + 1);
for(int i = 1; i <= N; i++) {
for(int j = 1; j <= N; j++) {
f[i][j] = max(f[i - 1][j], f[i][j - 1]);
if(s[i][j] == `a`) f[i][j]++;
if(i + j - 1 - f[i][j] <= K) s[i][j] = `a`;
}
}
putchar(s[1][1]); vis[1][1] = 1;
for(int i = 3; i <= N << 1; i++) {//all step
char now = `z` + 1;
for(int j = 1; j < i; j++) { // num of down
if(j > N || (i - j > N)) continue;
if(!vis[j - 1][i - j] && !vis[j][i - j - 1]) continue;
now = min(now, s[j][i - j]);
}
putchar(now);
for(int j = 1; j < i; j++) { // num of down
if(j > N || (i - j > N)) continue;
if(!vis[j - 1][i - j] && !vis[j][i - j - 1]) continue;
if(s[j][i - j] == now) vis[j][i - j] = 1;
}
}
return 0;
}
/*
*/