pranay_teja
9/28/2018 - 6:47 AM

GFG Minimum Cost Path

#include<bits/stdc++.h>
using namespace std;

// #GFG #Backtracking #DynamicProgramming
// https://practice.geeksforgeeks.org/problems/minimum-cost-path/0

int minCost(vector< vector<int> > a, int n);
void minCostSolve(vector< vector<int> > a,int n, map< pair<int,int>, pair<bool,int> > &memo,
                    map<pair<int,int>,bool > &visited, int x,int y,int &ans,  bool &valid);

int main(){
    //freopen("ip.txt","r",stdin);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        vector< vector<int> > a(n);
        for(int i=0;i<n;i++){
            a[i].resize(n);
            for(int j=0;j<n;j++){
                cin>>a[i][j];
            }
        }
        cout<<minCost(a,n)<<endl;
    }

    return 0;
}
int minCost(vector< vector<int> > a, int n){
    map< pair<int,int>, pair<bool,int> > memo; // (x,y)th element stores minCost to reach from (x,y) to end
    map<pair<int,int>,bool > visited;
    int ans;
    bool valid;
    minCostSolve(a,n,memo,visited,0,0,ans,valid);
    return ans;
}

void minCostSolve(vector< vector<int> > a,int n, map< pair<int,int>, pair<bool,int> > &memo,
                    map<pair<int,int>,bool > &visited, int x,int y,int &ans, bool &valid){
    if(x==n-1 && y==n-1){
        visited[{x,y}]=true;
        memo[{x,y}].second=a[x][y];
        memo[{x,y}].first=true;
        valid=true;
        ans= memo[{x,y}].second;
        return;
    }
    if(memo[{x,y}].first==true){
        valid=true;
        ans= memo[{x,y}].second;
        return;
    }
    if(x<0 || y<0 || x>=n || y>=n || visited[{x,y}]==true){
        valid=false;
        return; // if out of bounds/already visited, return
    }
    visited[{x,y}]=true;
    int min=INT_MAX;
    int right;
    minCostSolve(a,n,memo,visited,x,y+1,right,valid);
    if(valid==true && min>right){
        min=right;
    }
    int down;
    minCostSolve(a,n,memo,visited,x+1,y,down,valid);
    if(valid==true && min>down){
        min=down;
    }
    int left;
    minCostSolve(a,n,memo,visited,x,y-1,down,valid);
    if(valid==true && min>left){
        min=left;
    }
    int up;
    minCostSolve(a,n,memo,visited,x-1,y,up,valid);
    if(valid==true && min>up){
        min=up;
    }
    memo[{x,y}].second=min+a[x][y];
    memo[{x,y}].first=true;
    ans= memo[{x,y}].second;
    valid=true;
    return;
}