求矩阵的最大和路径问题

题目描述:有一个m×n的矩阵,现要从左下角走到右上角,并且方向只能是向上或者向右,

现规定一条路径的权值为走此路径所经过的值的和。给定一个矩阵,请找出权值最大的一条

路径。

Example
2 5 6
3 9 4
7 9 1

所找到的路径为7->9->9->5->6



解决思路:

由于路径只能向上或者向右进行,因此:

(0,0)(i,j)的最大累积和=(i,j)点的矩阵值+max{(0,0)(i-1,j)的累积和,(0,0)(i,j-1)的累积和},

因此可以依次计算到(0,0)点的距离为1,2...i的所有点的最大累积和,并记录每个点上取得最大累积和时所经过的路径.

距离为i的所有点表示为(j,i-j), j=0,1...i   注意j不要超过[0,m-1]的行数范围限制,i-j不要超过[0,n-1]的列数范围限制.

注意以下的几个if分支不能进行合并


具体代码如下:

非递归算法:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int StationArrary[3][3] = {7,9,1,3,9,4,2,5,6};

typedef struct MaxPeopleRecord {
    int totalnum;
    int pathflag;
} MaxPeopleRecord;

int PathGet(int *Arrary,int linenum,int colnum) {
    int i = 0,j = 0,pathflag = 0,start = 0, end = 0;    
    MaxPeopleRecord *maxrecord = malloc(colnum*linenum*sizeof(MaxPeopleRecord));
    memset(maxrecord,0,colnum*linenum*sizeof(MaxPeopleRecord));

    for(i = 1;i <= colnum + linenum - 2;i++){
        start = (i < colnum) ? 0 : (i - colnum + 1);
        end = (i < linenum) ? i : (linenum - 1);
        for(j = start; j <= end; j++){
            if(j == 0){
                maxrecord[j*colnum+i-j].totalnum = Arrary[j*colnum+i-j] + maxrecord[j*colnum+i-j-1].totalnum;
                maxrecord[j*colnum+i-j].pathflag = maxrecord[j*colnum+i-j-1].pathflag | (1 << i);
            }
            else if(j == i){
                maxrecord[j*colnum+i-j].totalnum = Arrary[j*colnum+i-j] + maxrecord[(j-1)*colnum+i-j].totalnum;
                maxrecord[j*colnum+i-j].pathflag = maxrecord[(j-1)*colnum+i-j].pathflag;
            }
            else if(maxrecord[j*colnum+i-j-1].totalnum >= maxrecord[(j-1)*colnum+i-j].totalnum) {
                maxrecord[j*colnum+i-j].totalnum = Arrary[j*colnum+i-j] + maxrecord[j*colnum+i-j-1].totalnum;
                maxrecord[j*colnum+i-j].pathflag = maxrecord[j*colnum+i-j-1].pathflag | (1 << i);
            }
            else if(maxrecord[j*colnum+i-j-1].totalnum < maxrecord[(j-1)*colnum+i-j].totalnum) {
                maxrecord[j*colnum+i-j].totalnum = Arrary[j*colnum+i-j] + maxrecord[(j-1)*colnum+i-j].totalnum;
                maxrecord[j*colnum+i-j].pathflag = maxrecord[(j-1)*colnum+i-j].pathflag;
            }
        }
    }
    pathflag = maxrecord[(linenum-1)*colnum+colnum-1].pathflag;
    free(maxrecord);
    return pathflag;
}


void main() {
    int line = 3,col = 3,i = 0,linetmp = 0,coltmp = 0;
    int pathflag = PathGet(&StationArrary[0][0],line,col);
    printf("path is :0x%x\n(0,0) ",pathflag);
    for(i = 1; i < col + line -1; i++) {
        linetmp += 1 - ((pathflag >> i) & 0x1);
        coltmp += (pathflag >> i) & 0x1;
        printf("(%d,%d) ",linetmp,coltmp);
    }
    getchar();
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值