返回一个二维整数数组中最大联通子数组的和
要求:
输入一个二维整形数组,数组里有正数也有负数。
求所有子数组的和的最大值。
吐槽:
这个算法不是特别好写,看了很多学长学姐的写法发现他们绝大多数的逻辑上都有硬伤,方法也很土(。。。),这个题我认为需要使用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 }
运行截图: