取数字问题
Time Limit: 1000 ms
Memory Limit: 65536 KiB
Problem Description
给定M×N的矩阵,其中的每个元素都是-10到10之间的整数。你的任务是从左上角(1,1)走到右下角(M,N),每一步只能够向右或者向下,并且不能够走出矩阵的范围。你所经过的方格里面的数字都必须被选取,请找出一条最合适的道路,使得在路上被选取的数字之和是尽可能小的正整数。
Input
输入第1行是两个整数M和N,(2<=M<=10,2<=N<=10),分别表示矩阵的行和列的数目。接下来M行,每行包括N个整数,就是矩阵中的每一行的N个元素。
Output
输出只有一行,就是一个整数,表示所选道路上数字之和所能达到的最小正整数。如果不能达到任何正整数,输出-1。
Sample Input
2 2 0 2 1 0
Sample Output
1
Hint
#include<stdio.h>
#include<string.h>
int a[12][12];
int b[12][12];
void minsum(int m,int n){
int i,j;
b[0][0]=a[0][0];
for(j=1;j<n;j++){
b[0][j]=a[0][j]+b[0][j-1];
}
for(i=1;i<m;i++){
b[i][0]=a[i][0]+b[i-1][0];
for(j=1;j<n;j++){
if(a[i][j]+b[i-1][j]<a[i][j]+b[i][j-1]){
b[i][j]=a[i][j]+b[i-1][j];
}
else{
b[i][j]=a[i][j]+b[i][j-1];
}
}
}
}
int main(){
int m,n;
scanf("%d %d",&m,&n);
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
scanf("%d",&a[i][j]);
}
}
memset(b,0,sizeof(b));
minsum(m,n);
printf("%d\n",b[m-1][n-1]);
return 0;
}
/*
分析:这是一个动态规划典型例题,首先我们从底向上分析,走到(M,N)那么可能经过(M-1,N)或者经过(M,N-1);
则必须满足走到(M-1,N)或者走到(M,N-1)之前的和是最小的,以此类推,在前面几章中介绍过,动态规划相当于一个表格,
将每次最优的值存在数组中,那么我可以这么想了,首先第一行所有值(1,1)的值肯定最小,
如果要走过(1,2)那么(1,1)+(1,2)的值肯定最下,走第一行和走第一列都是这样的性质,那么我将可能的第一行和第一列的值
都算出来,而(2,2)可以是(2,1)或者(1,2)走过来的,那么如果(1,2)+(2,2)小于(2,1)+(2,2)
那么(2,2)存得值就是(1,2)+(2,2),这必然是经过(2,2)最小的值,以此类推下去,直到推到(M,N)
那么(M,N)一定是最小的值
*/