1. 程式人生 > >返回一個二維整數數組中最大聯通子數組的和

返回一個二維整數數組中最大聯通子數組的和

一個 算法 ring 圖片 std void 數組 set 輸入

要求:

輸入一個二維整形數組,數組裏有正數也有負數。

求所有子數組的和的最大值。

技術分享圖片

吐槽:

這個算法不是特別好寫,看了很多學長學姐的寫法發現他們絕大多數的邏輯上都有硬傷,方法也很土(。。。),這個題我認為需要使用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 }

運行截圖:

技術分享圖片

返回一個二維整數數組中最大聯通子數組的和