標籤:講解 owa cst 數組 一個 bsp ali pac oid
要求:
輸入一個二維整形數組,數組裡有正數也有負數。
求所有子數組的和的最大值。
吐槽:
這個演算法不是特別好寫,看了很多學長學姐的寫法發現他們絕大多數的邏輯上都有硬傷,方法也很土(。。。),這個題我認為需要使用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 }
運行:
返回一個二維整數數組中最大聯通子數組的和