算法十分臃肿,效率捉鸡,不知用了多少循环,还有bug...任重道远,编程之美。
思想:按行遍历,找出每行的最大子数组。若行间都联通,行最大子数组相加后,再加上独立的正数。若行间不连通,找出较大子路径,再加上独立正数。
但是!有bug,写完之后想到的:每一行的最大子数组中的负数,有可能是不需要加上的。还没想好。
#include<iostream> using namespace std; /*int yiwei_max(int n,int a[],int *p,int *q) //自己写的函数,返回下标有问题,网上找了个核心思想和变量完全一样的。 { int temp=0,sum=-999999999,timer=-1; for(int i=0;i<n;i++) { if(temp>0) { temp+=a[i]; } else { temp=a[i]; } if(temp>sum) { sum=temp; *q=i; timer++; } } *p=*q-timer; return sum; }*/ int max_sum(int n,int a[],int *besti,int *bestj) { int *b = (int *)malloc(n * sizeof(int)); int sum = 0; int i = -1; int temp = 0; for (i=0;i<=n-1;i++) { if (temp > 0) { temp += a[i]; } else { temp = a[i]; } b[i] = temp; } sum = b[0]; for (i=1;i<=n-1;i++) { if (sum < b[i]) { sum = b[i]; *bestj = i; } } for (i = *bestj;i >= 0;i--) { if (b[i] == a[i]) { *besti = i; break; } } free(b); return sum; } void main() { int a[100][100],b[100]; int up[100],down[100],t[100]; int i,j,m,n,x,y; int temp,t2; int l=0,u=0,l_down,l_up,n_down,n_up; int s; cout<<"几行几列?"<<endl; cin>>m>>n; for(i=0;i<m;i++) { for(j=0;j<n;j++) { cin>>a[i][j]; } } for(i=0;i<m;i++) { for(j=0;j<n;j++) { b[j]=a[i][j]; } //temp=yiwei_max(n,b,&x,&y); temp=max_sum(n,b,&x,&y); up[i]=x; //记录每行下标、上标和最大值。 down[i]=y; t[i]=temp; } t2=t[0]; for(i=0;i+1<m;i++) { if(up[i]<=down[i+1] && down[i]>=up[i+1]) { t2+=t[i+1]; } else { l_down=down[i]; l_up=up[i]; n_up=up[i+1]; n_down=down[i+1]; if(down[i]<up[i+1]) //求数组两条路径的较大值 { for(;l_down!=up[i+1];) { l+=a[i][++l_down]; } for(;n_up!=down[i];) { u+=a[i+1][--n_up]; } } if(up[i]>down[i+1]) { for(;l_up!=down[i+1];) { l+=a[i][--l_up]; } for(;n_down!=up[i];) { u+=a[i+1][++n_down]; } } s=l>u?l:u; if(s+t[i+1]>0) { t2+=t[i+1]+s; } } for(j=up[i];j<down[i];j++) { if(a[i+1][j]>0) t2+=a[i+1][j]; //判别独立正数 } } cout<<t2<<endl; }