Project Euler #82: Path sum: three ways

Sort by

recency

|

15 Discussions

|

  • + 0 comments
    Python
    M, DP = [], []
    for _ in range(int(input())):
        M.append(list(map(int, input().split())))
        DP.append(M[-1][-1])
    
    for i in range(len(M)-2, -1, -1):
        DP[0] += M[0][i]
        for j in range(1, len(M)):
            DP[j] = min(DP[j], DP[j-1]) + M[j][i]
    
        for j in range(len(M)-2, -1, -1):
            DP[j] = min(DP[j], DP[j+1] + M[j][i])
    
    print(min(DP))
    
  • + 0 comments

    C++ Solution

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    long long ans;
    
    int main() 
    {
        cin >> n;
        
        vector<vector<long long>> M(n, vector<long long>(n));
        
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                cin >> M[i][j];        
            }        
        }    
        vector<long long> dp(n+1, 1e18);
                
        for(int i=0; i < n; i++)
        {
            dp[i] = M[i][n-1];     
        }    
        
        for(int i=n-2; i>=0; i--)
        {
            dp[0] += M[0][i];
            
            for(int j=1; j<n; j++)   
            {
                dp[j] = min(dp[j] + M[j][i], dp[j-1] + M[j][i]);
            }
            for(int j=n-2; j>=0; j--)
            {
                dp[j] = min(dp[j], dp[j+1] + M[j][i]);
            }
        }
        ans = *min_element(dp.begin(), dp.end());
        cout << ans << endl;
        
        return 0;
    }
    
  • + 0 comments

    I rotated the matrix so the starting becomes the right side and then used normal dp and in the end calculation i just take the minimum of last column. Sow why is my logic failing. It only passes 2 test cases and wrong answer for others but why?

    import sys
    l=[]
    for _ in range(int(input())):
        l.append(list(map(int,input().strip().split(" "))))
    
    n=len(l)
    cost=[]
    
    for i in range(n):
        cost.append(l[i][::-1])
    #print(cost)
    
    dp=[[0 for i in range(n)] for j in range(n)]
    
    for i in range(n):
        dp[i][0]=dp[i-1][0]+cost[i][0]
        
    for j in range(n):
        dp[0][j] = dp[0][j-1] + cost[0][j]   
    
    for i in range(1,n):
        for j in range(1,n):
            dp[i][j]=min(dp[i-1][j],dp[i][j-1]) + cost[i][j]
            
    #print(dp)      
    minimum=sys.maxsize
       
    for i in range(0,n-1):
        if minimum>dp[i][n-1]:
            minimum=dp[i][n-1]
            
    print(minimum)
        
    
  • + 0 comments

    I'm using Dijkstra with a PriorityQueue. It runs fast enough but is failing on tests 3 through 6

    <?php
    
    function euler082($matrix, $n): int
    {
        $graph = graph($matrix, $n);
    
        $length = count($graph);
        $distances = array_fill(0, $length, null);
        
        $target = $length - 1;
        $start = $target - 1;
        $pq = new MinPq();
        
        $distances[$start] = 0;
        $pq->insert($start, $distances[$start]);
        
        while (!$pq->isEmpty()) {
            list($curr, $dist) = $pq->extract();
            
            foreach ($graph[$curr] as $next => $next_dist) {
                $sum = $dist + $next_dist;
                if (is_null($distances[$next]) || $distances[$next] > $sum) {
                    $distances[$next] = $sum;
                    $pq->insert($next, $distances[$next]);
                }
            }
        }
        
        return $distances[$target];
    }
    
    function graph($matrix, $n) {
        $length = $n ** 2;
        $graph = [];
        
        $transforms = [
            # row, col, index
            [-1, 0, -$n],
            [0, -1, -1],
            [1, 0, $n],
            [0, 1, 1],
        ];
        
        // Connecting graph vertexes
        for ($index = 0; $index < $length; $index++) {
            list($row, $col) = ydiv($index, $n);
            foreach ($transforms as list($trow, $tcol, $tidx)) {
                $trow += $row;
                $tcol += $col;
                $tidx += $index;
                
                if (isset($matrix[$trow][$tcol])) {
                    $dist = $matrix[$trow][$tcol];
                    $graph[$index][$tidx] = $dist;
                }
            }
        }
    
        // Connecting start and target vertexes to first and last columns
        $start_index = $length;
        $target_index = $start_index + 1;
        for ($row = 0; $row < $n; $row++) {
            $first_col_idx = $row * $n;
            $last_col_idx = ($row + 1) * $n - 1;
            
            $graph[$start_index][$first_col_idx] = $matrix[$row][0];
            $graph[$first_col_idx][$start_index] = 0;
            
            $graph[$target_index][$last_col_idx] = $matrix[$row][$n - 1];
            $graph[$last_col_idx][$target_index] = 0;
        }
    
        return $graph;
    }
    
    class MinPq extends SplPriorityQueue
    {
        public function __construct()
        {
            $this->setExtractFlags(self::EXTR_BOTH);
        }
    
        public function extract()
        {
            return array_values(parent::extract());
        }
    
        public function compare($a, $b)
        {
            return -($a <=> $b);
        }
    }
    
    function ydiv(int $a, int $b): array
    {
        return [
            intval($a / $b),
            $a % $b,
        ];
    }
    
    function gets(): string
    {
        return trim(fgets(STDIN));
    }
    
    function puts(string $str): void
    {
        echo $str, PHP_EOL;
    }
    
    function logs($var): void
    {
        ob_start();
        if (is_scalar($var)) {
            puts($var);
        } else {
            var_dump($var);
        }
        error_log(trim(ob_get_clean()));
    }
    
    $n = intval(gets());
    
    for ($i = 0; $i < $n; $i++) {
        $matrix[$i] = array_map('intval', explode(' ', gets()));
    }
    
    puts(euler082($matrix, $n));
    
  • + 0 comments

    I used Dijkstra's Algorithm (using heapq (similar to priority queue) of Python), graph is such that there is a source vertex and n^2 other vertices. Edges from source vertex to the vertices of the first column are having weight = grid(i,0) for i=0 to n-1 and all other vertices (i,j) have incoming edges (from left to right, up to down, down to up) with weight=grid(i,j). Then take the minimum dist(i,n-1) for i=0 to n-1.
    Works fine in Python 3 but avoid creating a "Graph". Use list not dictionary. dict is very slow. Only for source, adjacent vertices have a condition, for all other vertices, the conditions are same so it can be solved without actually building a graph with adjacency lists and costs.
    Even Dijkstra's Algorithm worked in O(n^2) by just adding one extra vertex.