codeforces 1031D. Minimum path(bfs+dp)
阿新 • • 發佈:2018-11-11
題解:
bfs的時候考慮下那k個可以改變的次數用完沒就好了,然後邊dp邊記錄答案,d1代表走到當前格子需要多少步,d2代表走過的格子中有多少已經是'a'了,說明不需要變換,則,d1-d2代表有多少格子不為'a'的。那麼當d1-d2 <= k時,之前的全部都能變成'a'
#include<bits/stdc++.h> #define mp make_pair #define fir first #define sec second using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int MX = 2004; char s[MX][MX]; int d1[MX][MX], d2[MX][MX]; char ans[MX*2]; int xi[]={0,1}; int yi[]={1,0}; struct node{ int x,y; node(){} node(int x, int y) :x(x), y(y) {} }; void bfs(int n, int m) { queue<node> que; que.push(node(1,1)); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) d1[i][j] = INF, d2[i][j] = 0; d1[1][1] = 1, d2[1][1] = (s[1][1] == 'a'); for(int i = 1; i <= 2*n-1; i++) ans[i] = 'z'; ans[1] = (s[1][1] == 'a' || m > 0)? 'a' : s[1][1]; while(!que.empty()){ node e = que.front(); que.pop(); int pos = e.x+e.y-1; if(d1[e.x][e.y]-d2[e.x][e.y] > m && s[e.x][e.y] > ans[pos]) continue; for(int i = 0; i < 2; i++){ int xx = e.x+xi[i], yy = e.y+yi[i]; if(xx > n || yy > n) continue; int flag = (s[xx][yy] == 'a' && (d1[e.x][e.y] - d2[e.x][e.y]) <= m); if(d1[xx][yy] > d1[e.x][e.y] + 1){ d1[xx][yy] = d1[e.x][e.y] + 1; d2[xx][yy] = d2[e.x][e.y] + flag; que.push(node(xx,yy)); ans[pos+1] = min(ans[pos+1], (d1[xx][yy]-d2[xx][yy] <= m)? 'a' : s[xx][yy]); } else if(d2[xx][yy] < d2[e.x][e.y] + flag ){ d2[xx][yy] = d2[e.x][e.y] + flag; ans[pos+1] = min(ans[pos+1], (d1[xx][yy]-d2[xx][yy] <= m)? 'a' : s[xx][yy]); } else { ans[pos+1] = min(ans[pos+1], s[xx][yy]); } } } } int main() { #ifdef LOCAL freopen("input.txt","r",stdin); #endif // LOCAL int n,m; scanf("%d%d",&n,&m); for(int i = 1; i<= n; i++) scanf("%s",s[i]+1); bfs(n,m); printf("%s",ans+1); return 0; } /* 4 2 abcd bcde bcad bcde */