dp之取数字问题

题目:

  给定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 }

这一题从答案入手,判断该答案是否存在,是我到目前为止没怎么接触过的解法,记录在这,姑且叫做从答案入手吧。。

 

posted on 2017-03-25 15:50  子狼  阅读(260)  评论(0)    收藏  举报

导航