1. 程式人生 > >poj2078 Matrix(DFS)

poj2078 Matrix(DFS)

[] mes inf clas namespace pre r+ 右移 ems

題目鏈接

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);)也可以通過,但花費的時間會長一些。

poj2078 Matrix(DFS)