1. 程式人生 > >codeforces 1031D. Minimum path(bfs+dp)

codeforces 1031D. Minimum path(bfs+dp)

題解:

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
*/