返回一个二维整数数组中最大联通子数组的和

 

要求:

输入一个二维整形数组,数组里有正数也有负数。

求所有子数组的和的最大值。

吐槽:

这个算法不是特别好写,看了很多学长学姐的写法发现他们绝大多数的逻辑上都有硬伤,方法也很土(。。。),这个题我认为需要使用DFS遍历+DP动态规划搞定,设计上不详细讲解了,比较麻烦。

 

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<set> 
 4 using namespace std;
 5 int map[15][15];
 6 bool v[15][15];
 7 set<long long> dp;
 8 int ans,m,n;
 9 int xd,yd;
10 int x[4]={1,0,-1,0};
11 int y[4]={0,1,0,-1};
12 bool isOK(int x,int y){
13     if(x<1||y<1)return 0;
14     if(x>m||y>n)return 0;
15     return 1;
16 }
17 long long toNUM(){
18     long long a=0;
19     for(int i=1;i<=m;i++){
20         for(int j=1;j<=n;j++){
21             if(v[i][j]){
22                 long long s=1<<((i-1)*m);
23                 s=s<<(j-1);
24                 a=a|s; 
25             }
26         }
27     }
28     return a;
29 }
30 int c=0;
31 void dfs(int nowAns){
32     if(nowAns>ans){
33         ans=nowAns;
34     }
35     for(int ii=1;ii<=m;ii++){
36         for(int jj=1;jj<=n;jj++){
37             if(v[ii][jj]){
38                 for(int i=0;i<4;i++){
39                     if(isOK(ii+x[i],jj+y[i])&&(v[ii+x[i]][jj+y[i]]==0)){
40                         v[ii+x[i]][jj+y[i]]=1;
41                         long long s=toNUM();
42                         if(dp.count(s)==0) c++,dp.insert(s),dfs(nowAns+map[ii+x[i]][jj+y[i]]);
43                         v[ii+x[i]][jj+y[i]]=0;
44                     }
45                 }
46             }           
47         }
48     }
49 }
50 int main(){
51     cin>>m>>n;
52     for(int i=1;i<=m;i++){
53         for(int j=1;j<=n;j++){
54             cin>>map[i][j];
55         }
56     }
57     for(int i=1;i<=m;i++){
58         for(int j=1;j<=n;j++){
59             xd=i;yd=j;
60             v[i][j]=1;
61             dfs(map[i][j]);
62             memset(v,0,sizeof(v));
63         }
64     }
65     cout<<c<<endl;
66     cout<<ans<<endl;
67     return 0;
68 }

 运行截图:

 

 

 

 

 

posted @ 2017-12-15 23:54  messi2017  阅读(102)  评论(0编辑  收藏  举报