poj2078 Matrix(DFS)

题目链接

http://poj.org/problem?id=2078

题意

输入一个n×n的矩阵,可以对矩阵的每行进行任意次的循环右移操作,行的每一次右移后,计算矩阵中每一列的和的最大值,输出这些最大值中的最小值。

思路

使用dfs解决,对于n×n的矩阵来说,行循环右移后,矩阵最多有n^n中可能的状态,在这题中最多有7^7=823543中状态,是可以暴力搜索的。使用dfs搜索这些状态,并计算矩阵每个状态的列和的最大值,输出最大值中的最小值即可。

代码

 1  #include <iostream>
 2  #include <cstdio>
 3  #include <cstring>
 4  using namespace std;
 5 
 6  const int INF = 1<<30;
 7 
 8  const int N = 10;
 9  int a[N][N];
10  int n;
11  int minNum;
12 
13  void rotate(int r)     //对行a[r][]循环右移一次
14  {
15      int t = a[r][n-1];
16      for(int i=n-1; i>0; i--)
17         a[r][i] = a[r][i-1];
18      a[r][0] = t;
19  }
20 
21  void dfs(int r)
22  {
23      int maxNum = -INF;     //列和的最大值
24      if(r==n)
25      {
26          for(int j=0; j<n; j++)
27          {
28              int sum = 0;
29              for(int i=0; i<n; i++)
30                 sum += a[i][j];
31              if(sum>maxNum)
32                 maxNum = sum;
33          }
34          if(maxNum<minNum)
35             minNum = maxNum;     //保存列和最大值中的最小值
36      }
37      else
38      {
39          for(int i=0; i<n; i++)    //每一行都循环右移n次
40          {
41              rotate(r);
42              dfs(r+1);
43          }
44      }
45  }
46 
47  int main()
48  {
49      //freopen("poj2078.txt", "r", stdin);
50     while(cin>>n)
51     {
52         if(n==-1)
53             return 0;
54 
55         memset(a, 0, sizeof(a));
56         for(int i=0; i<n; i++)
57             for(int j=0; j<n; j++)
58                 cin>>a[i][j];
59 
60         minNum = INF;
61         dfs(1);          //从第1行开始搜索可以节省时间
62         cout<<minNum<<endl;
63     }
64     return 0;
65  }

注意点

1、由于矩阵的循环右移是相对的,所以第0行不动,从第1行开始搜索会节省时间,从第0行开始搜索(dfs(0);)也可以通过,但花费的时间会长一些。

原文地址:https://www.cnblogs.com/sench/p/7819475.html