题目:
给定M*N矩阵, 其中每个元素都是-10~10之间的整数。你的任务是从左上角(1, 1)到右下角(m, n),每一步只能现有或向下,并且不能走出矩阵的范围, 你所经过的方格里的数字必须被选取, 找出一条最合适的道路,使得在路上被选取的数字之和是尽可能的小的正整数。
分析:
注意是正整数。 当处于(m, n)时候总和必须大于0, 那么当处于(m ,n)上一格的总和必须大于 0 - A(m , n) (m, n处的数值), 以此类推,每一格都有一个必须达到的数值,把这个必须达到的数值加入数组,M[x][y][num] /*x行y列必须达到的数字num是否存在*/ , 用dp出来(自己写的时候只看题解也是没写出来,到后来还是看的代码,代码挺容易懂,只是思路很神奇,还是要多练)
代码:
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 int N[12][12], M[12][12][2005]; 5 int m, n; 6 int solve(int x, int y, int num) 7 { 8 int &res = M[x][y][num+1000]; 9 if(res != -1) return res; 10 if(!x && !y) return res = (num == N[0][0]); 11 if(x && solve(x-1, y, num - N[x][y])) return res = 1; 12 if(y && solve(x, y-1, num - N[x][y])) return res = 1; 13 return res = 0; 14 } 15 16 int main() 17 { 18 while(cin >> m >> n) 19 { 20 for(int i = 0; i < m; i++) 21 { 22 for(int j = 0; j < n; j++) 23 cin >> N[i][j]; 24 } 25 memset(M, -1, sizeof(M)); 26 int ans = -1; 27 for(int i = 1; i <= m*n*20; i++) 28 { 29 if(solve(m-1, n-1, i)) 30 {ans = i;break;} 31 } 32 cout << ans << endl; 33 } 34 return 0; 35 }
这一题从答案入手,判断该答案是否存在,是我到目前为止没怎么接触过的解法,记录在这,姑且叫做从答案入手吧。。