M*N的矩阵

来源:互联网 发布:淘宝店招手机客户端 编辑:程序博客网 时间:2024/04/30 06:44

/*

给定一个M*N的矩阵,其中的每个元素都是-10到之间的整数。你的任务是从左上角(1,1)开始走到右下角(M,N),

每一步只能够向右或者向下,并且不能够走出矩阵的范围。所经过的方格里的数字都必须被选取,

请找出一条最合适的道路,使得在路上被选取的数字之和尽可能小的整数。

*/

 

/*分析:

   从左上角走到第xy列时,所取数的和为d,这个状态能否到达?

   0 <= x <= 10,  0 <= x <= 10,-1000 <= d <= 1000,所以状态数是*11*2001,是可以接受的范围;

   然后考虑如何用递归求解各个子问题,到达(x,y)有两种情况,一是从上方走下来,另一个是从左边

   走过来,其中一个可到达,则本状态可以到达。

   即:若"x>0 && {x-1,y,d-a[x][y]}可以到达",或"y>0&& {x,y-1,d-a[x][y]}可以到达"

   {x,y,d}可以到达。

   {m,n,i},i从到n*m*20查找一遍,取最小值。

*/

 

#include <stdio.h>

#include <string.h>

 

int m,n;//m*n的矩阵

int a[10][10]; //矩阵信息

char f[10][10][2010];  // 状态数

 

//就是从左上角走到(x,y)的时候所取的数字和能都为d

bool solve(int x,int y ,int d)

{

    //把结果记录在f[x][y][1000+d],因为d可能为负数

    char &res=f[x][y][d+1000];

    //若已经求解则返回结果

    if(res!=-1) return res;

    //递归求结果

    if(x == 0 && y == 0) return res = ( d == a[0][0] );  //是第一个点,且当前数字和为a[0][0] 可以达到

    if(x&&solve(x-1,y,d-a[x][y])) return res = 1;

    if(y&&solve(x,y-1,d-a[x][y]))  return res =1;

    return res=0;

}

 

 

int main()

{

    freopen("input.txt","r",stdin);

    while(scanf("%d%d",&m,&n)!=EOF)

    {

       int i;

        for(i=0;i<m;i++)

           for(int j=0;j<n;j++)

           {

              scanf("%d",&a[i][j]);

           }

           memset(f,255,sizeof(f));

           int ans = -1;

           //求最小可以到达的数

           for(i=1;i<=m*n*20;i++)

              if(solve(m-1,n-1,i))

              {

                  ans = i;break;

              }

 

              printf("%d/n",ans);

    }

    return 0;

}

 

测试数据:           输出结果:

4 3                   11

5 7 1

2 -2 7

-4 4 4

-9 9 8

原创粉丝点击