您的位置:首页 > 其它

ACM: 训练题 动态规划题 (蛮有意思…

2016-05-19 23:21 351 查看
[align=center]取数字问题[/align]
 
Description

定的M*N的矩阵,其中的每个元素都是-10到10之间的整数,你的任务是从左上角(1,1),走到右下角(M,N),每一步只能向下或者向右,你所经过的方格里面的数字都必须被选取,请找出一条最合适的路,使得在路上被选取的数字之和是尽可能小的正整数。

Input
测试数据包括多组,以文件结尾为结束。

第一行:两个正整数M,N(2=<M,N<=10);

接下来的M行:每行包括N个整数,是矩阵中每一行的N个元素。

Output
输出只有一行,就是一个整数,表示所选道路上数字之和所能达到的最小正整数。如果不能达到任何正整数,输出-1。

Sample Input
2 2

0 2

1 0

Sample Output
1
 
题意: 从(1,1)-->(n,m)的位置累加每一步的值,求出最接近0的正整数.
 
解题思路: 

          
1. 这题思路是: 逆向思维: 从结果返回来推导路径是否满足.

              问题解析:
正向思维: 深搜枚举每一条路径, 并且最后的结果要最接近0的正整数.

           2.
显然, 逆向思维可以更快找出结果. (头脑发热想出来了.)

           3.
奉献了好多次WA居然没看到找不到要输出-1  (T.T)
 
代码:
#include <cstdio>

#include <iostream>

#include <cstring>

#include <cmath>

using namespace std;

#define MAX 12
int n, m;

int a[MAX][MAX];

int dp[MAX][MAX][210];
int DP(int i,int j,int result)

{

 if(dp[i][j][result] != -1) return
dp[i][j][result];

 int ans = 0;

 if(i == 1 && j ==
1)

 {

  if(result == a[1][1])

  {

   ans =
1;

   return
ans;

  }

 }
 if(i != 1)

 {

  if( DP(i-1,j,result-a[i][j])
)

   ans =
1;

 }
 if(j != 1)

 {

  if( DP(i,j-1,result-a[i][j])
)

   ans =
1;

 }

 dp[i][j][result] = ans;

 return ans;

}
int main()

{

 int i, j;

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

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

 {

  for(i = 1; i <=
n; ++i)

   for(j = 1; j
<= m; ++j)

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

  memset(dp,-1,sizeof(dp));

  bool flag = false;

  for(i = 1; i <=
205; ++i)

  {

   if( DP(n,m,i)
== 1)

   {

    printf("%d\n",i);

    flag
= true;

    break;

   }

  }

  if(!flag) printf("-1\n");

 }

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: