Friday, 10 February 2012

[Euler Problem]: Finding the minimum sum

In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by only moving to the right and down, is indicated in bold red and is equal to 2427.

13167323410318
20196342965150
630803746422111
537699497121956
80573252437331



This can be solved by an easy application of the DP.
A nice variation of the  above problem is to find the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold red and is equal to 2297.


13167323410318
20196342965150
630803746422111
537699497121956
80573252437331


Here is my code. I applied Dijkstra in order to solve this problem.


#include<stdio.h>
#include<conio.h>
struct room
{
    int x,y;
    int count;
};

struct room heap[5000];
int size;

int board[71][71];
int count[71][71];
int flag[72][72];

void insert_heap(int x,int y,int count)
{
    int i;
    struct room temp;
    heap[++size].x = x;
    heap[size].y = y;
    heap[size].count = count;
    i = size;
    while(i>1)
    {
        if(heap[i].count<heap[i/2].count)
        {
            temp = heap[i];
            heap[i] = heap[i/2];
            heap[i/2] = temp;
            i/=2;
        }  
        else
           break;
    }  
}

struct room remove_heap()
{
    int i = 1,loc,min;
    struct room minroom = heap[1],temp;
    heap[1] = heap[size--];
   
    while(i<size)
    {
        loc = i;
        min = heap[i].count;
        if(2*i<=size)
        {
            if(heap[2*i].count< min)
            {
                loc = 2*i;
                min = heap[2*i].count;
            }  
        }
        if(2*i+1<=size)
        {
            if(heap[2*i+1].count< min)
            {
                loc = 2*i+1;
            }
        }
       
        if(loc!=i)
        {
            temp = heap[i];
            heap[i] = heap[loc];
            heap[loc] = temp;
            i = loc;
        }
        else
           break;        
    }
   
    return minroom;
   
}
   

int main()
{
    int rows,cols;
    int targetx,targety,threshhold;
    struct room min;
    scanf("%d",&rows);
    cols=rows;
    int i,j,k;
    int minx,miny;
    for(i=1;i<=rows;i++)
    {
        for(j=1;j<=cols;j++)
        {
            scanf("%d",&board[i][j]);
        }  
    }
    targetx=rows;
    targety=cols;
    for(i=0;i<=rows+1;i++)
    {
        flag[i][0] = 1; flag[i][cols+1] =1;
    }  
    for(j=0;j<=cols+1;j++)
    {
        flag[0][j] = 1; flag[rows+1][j] =1;
    }  
     
    insert_heap(1,1,board[1][1]);
    count[1][1] = board[1][1];
    flag[1][1] = 1;  
   
    while(size!=0)  
    {
        min = remove_heap();
        minx = min.x; miny = min.y;
       
        if(minx == targetx && miny == targety )
            break;
        if(flag[minx-1][miny]!=1)
        {
            insert_heap(minx-1,miny, min.count + board[minx-1][miny]);
            count[minx-1][miny] = min.count + board[minx-1][miny];
            flag[minx-1][miny] = 1;
        }
        if(flag[minx+1][miny]!=1)
        {
            insert_heap(minx+1,miny, min.count + board[minx+1][miny]);
            count[minx+1][miny] = min.count + board[minx+1][miny];
            flag[minx+1][miny] = 1;
        }
        if(flag[minx][miny-1]!=1)
        {
            insert_heap(minx,miny-1, min.count + board[minx][miny-1]);
            count[minx][miny-1] = min.count + board[minx][miny-1];
            flag[minx][miny-1] = 1;
        }
        if(flag[minx][miny+1]!=1)
        {
            insert_heap(minx,miny+1, min.count + board[minx][miny+1]);
            count[minx][miny+1] = min.count + board[minx][miny+1];
            flag[minx][miny+1] = 1;
        }      
    }
   
            printf("%d\n",min.count);
    getch();
    return 0;  
 
}  



No comments:

Post a Comment