您的位置:首页 > 其它

最大连通子数组求和

2016-04-06 17:16 369 查看
//求最大联通子数组和 张鹏宇 武于微
/****************************************************************
题目要求:

文件读入二维数组,计算最大联通子数组的和

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

2.数组中有正数,也有负数

3.求所有子数组的最大值

4.程序要使用的数组放在txt文件中

*****************************************************************/

#include<iostream>
#include<cmath>
#include <fstream>
const int N = 500;
const int INF = -9999;
using namespace std;
/**************************************************************************************************************************

int Only(bool flag,int a,int b,int num1[],int *p)             //前后标志,起始位置,终止位置,动态规划部分,成功标志
{
int p1,p2;   //开始位置结束位置
int f1,f2;
int max=MAXNUM(b-a,num1,&p1,&p2);
f1=p1;
f2=p2;
if((flag==1&&f2<b)||(flag==0&&f1>b))//起始
*p=0;
else
*p=1;
return max;
}
*******************************************************************************************************************************/
int MAXNUM(int num,int a[],int *p,int *f)      //动态规划一维数组
{
int dp[200][2],CMax,Q=1;
for(int j=0;j<num;j++)
{
dp[j][0]=max(dp[j-1][0],dp[j-1][1]);
dp[j][1]=max(dp[j-1][1]+a[j],a[j]);
CMax=max(dp[j][0],dp[j][1]);
if(dp[j][1]==a[j])
{
if(CMax==dp[j][1])
{
*p=j;
*p=j;
Q=0;
}
}
else if(dp[j][1]==(dp[j-1][1]+a[j])&&CMax==dp[j][1])
{
if(Q==0)
*f=j;
else
*p=j;
}
}
return CMax;
}

int findMaxSubMatrix()
{
int num,Num,Max,number[200][200],dp[200][2],CMax[200],flag[200][200]={0},up[200],down[200],Q=1;
ifstream in("Zhangpy.txt");
in>>num;
in>>Num;
for (int i=0; i<num; i++)
{
for (int j=0; j<Num; j++)
in>>number[i][j];
}

for(int i=0;i<num;i++)/***********第N行**********/
{
for(int j=0;j<Num;j++)/***********前N个**********/
{
dp[j][0]=max(dp[j-1][0],dp[j-1][1]);
dp[j][1]=max(dp[j-1][1]+number[i][j],number[i][j]);
CMax[i]=max(dp[j][0],dp[j][1]);
if(dp[j][1]==number[i][j])
{
for(int k=0;k<Num;k++)
flag[i][k]=0;
if(CMax[i]==dp[j][1])
{
flag[i][j]=1;
up[i]=j;
down[i]=j;
Q=0;
}
}
else if(dp[j][1]==(dp[j-1][1]+number[i][j])&&CMax[i]==dp[j][1])
{
flag[i][j]=1;
if(Q==0)
down[i]=j;
else
up[i]=j;
}
else
flag[i][j]=0;
}
//cout<<CMax[i];
}

int F=1;
for(int i=0;i<num-1;i++)     //第i行
{
F=1;
int j;
for(j=0;j<Num&&F==1;j++)     //扫描下一行
{
if(flag[i][j]==1&&flag[i+1][j]==1)
{
CMax[i]=CMax[i+1]+CMax[i];
CMax[i+1]=CMax[i];
F=0;
}
}
/*************************************************************************************************************
if(F==0)     //两行                                                  //两行周围动态规划,失败。。。。
{
int p,f;
for(int j=0;j<Num;j++)
{
if(up[i]>up[i+1])     //第一行行前靠后
{
int DP[200][2];
int maxa;
maxa=MAXNUM(up[i]-up[i+1],number[i],&p,&f);
if(p>=up[i+1]&&p<=up[i])
{
for(int m=up[i+1];m<p;m++)
flag[i][m]=0;
CMax[i]=CMax[i]+maxa;
CMax[i+1]=CMax[i];
}
else
{
for(int m=up[i+1];m<up[i];m++)
{
if(number[i][m]>0)
{
CMax[i]=CMax[i]+number[i][m];
flag[i][m]=1;
CMax[i+1]=CMax[i];
}
}
}

}
else                  //第一行行前靠前
{
int DP[200][2];
int maxa;
maxa=MAXNUM(up[i+1]-up[i],number[i+1],&p,&f);
if(p>=up[i]&&p<=up[i+1])
{
for(int m=up[i];m<p;m++)
flag[i][m]=0;
CMax[i]=CMax[i]+maxa;
CMax[i+1]=CMax[i];
}
else
{
for(int m=up[i];m<up[i+1];m++)
{
if(number[i+1][m]>0)
{
flag[i][m]=1;
CMax[i]=CMax[i]+number[i+1][m];
CMax[i+1]=CMax[i];
}
}
}
}
if(down[i]>down[i+1])     //第一行后前靠后
{
int DP[200][2];
int maxa;
maxa=MAXNUM(down[i]-down[i+1],number[i],&p,&f);
if(p>=up[i+1]&&p<=up[i])
{
for(int m=p;m<down[i];m++)
flag[i][m]=0;
CMax[i]=CMax[i]+maxa;
CMax[i+1]=CMax[i];
}
else
{
for(int m=down[i+1];m<down[i];m++)
{
if(number[i+1][m]>0)
{
flag[i][m]=1;
CMax[i]=CMax[i]+number[i+1][m];
CMax[i+1]=CMax[i];
}
}
}
}
else                  //第一行行后靠前
{
int DP[200][2];
int maxa;
maxa=MAXNUM(down[i+1]-down[i],number[i+1],&p,&f);
if(p>=up[i]&&p<=up[i+1])
{
for(int m=p;m<down[i+1];m++)
flag[i][m]=0;
CMax[i]=CMax[i]+maxa;
CMax[i+1]=CMax[i];
}
else
{
for(int m=down[i];m<down[i+1];m++)
{
if(number[i][m]>0)
{
CMax[i]=CMax[i]+number[i][m];
flag[i][m]=1;
CMax[i+1]=CMax[i];
}
}
}
}
}
}

*************************************************************************************************************/

/*********************************************************************************************************
if(F==0)    //两行                                            //两行未完成
{
int p,nummax,arry[200],arry1[200];
int an[4];
for(int m=0;m<Num;m++)
{
arry[m]=number[i][m];
arry1[m]=number[i+1][m];
}
if(up[i]>up[i+1])
{
nummax=Only(1,up[i+1],up[i],arry,&p);
an[0]=p;
}
else
{
nummax=Only(1,up[i],up[i+1],arry1,&p);
an[1]=p;
}
if(down[i]>down[i+1])
{
nummax=Only(0,down[i+1],down[i],arry1,&p);
an[2]=p;
}
else
{
nummax=Only(0,down[i],down[i+1],arry,&p);
an[3]=p;
}

}
**************************************************************************************************************/
if(F==1)    //一行
{
for(int k=0;k<Num;k++)
flag[i+1][k]=0;
for(int j=up[i];j<down[i]+1;j++)
{
if(number[i+1][j]>0)
{
flag[i+1][j]=1;
CMax[i]=CMax[i]+number[i+1][j];
CMax[i+1]=CMax[i];
}
}
}

}

Max=CMax[0];
for(int i=1;i<num;i++)
if(CMax[i]>Max)
Max=CMax[i];

return Max;
}

int main()
{
int M;
ofstream outfile;
outfile.open("Zhangpy.txt",ios::out|ios::app);
if(!outfile)
{
cout<<"open error!"<<endl;
}
M=findMaxSubMatrix();
cout<<endl;
outfile<<"最大子数组的和为: "<<M<<endl;
outfile.close();
}






思路:

利用动态规划求出每一行的最大子数组

并标记最大子数组中的数flag为1

根据flag求出up[],down[],标记最大子数组起始结束位置,用来判断单个数

根据flag值判定是否联通,若联通则相加,不联通继续扫描

若有多行联通——————(bug)

若只有一行,扫描下一行与之相联通的数,若是整数则相加,负数不做动作

以此为基础形成迭代

缺陷:

由于使用动态规划做得,导致若有几行最大子数组相连时无法判断单个正数,所求最大连通子数组的和偏小

项目计划总结:

日期&&任务

听课

编写程序

阅读相关书籍

网上查找资料

日总计

周一

2

2

1

1

6

周二

2

1

1

4

周三

1

2

2

5

周四

2

1

1

1

5

周五

4

1

1

6

周六

2

2

周日

4

2

6

周总计

4

16

8

6

34

时间记录日志:

日期

开始时间

结束时间

中断时间

净时间

活动

备注

3/28

14:00

15:50

10

100

听课

软件工程上课

16:10

18:30

20

120

编写程序

合作编写求最大连通子数组和的程序

19:00

20:10

10

60

编程,网上查资料

编写求最大连通子数组和,上网查找相关资料

21:00

22:00

60

阅读书籍

《构建之法》

3/29

18:30

22:30

20

220

查资料,编写程序

编写求最大连通子数组和的程序,查阅相关资料,改善程序不足

3/30

16: 00

22:10

90

280

阅读书籍,编写程序

学习安卓知识,试编写安卓版四则运算3

3/31

14:00

15:50

10

100

听课

软件工程上课

19:00

22:30

30

180

阅读书籍资料,编写程序

合作编写安卓版四则运算3,学习相关安卓知识

4/1

14:00

18:30

10

230

编写程序

合作编写安卓版四则运算3程序,请教同学相关知识

19:30

20:40

10

60

阅读书籍资料

学习安卓知识

22:20

23:30

70

阅读书籍

《构建之法》

4/2

19:00

21:50

30

140

编写程序

合作编写安卓版四则运算3程序

4/3

14: 30

18:30

240

编写程序

合作编写安卓版四则运算3程序

20:10

21:30

20

60

阅读书籍

《构建之法》

缺陷记录日志:

日期

编号

类型

引入阶段

排除阶段

修复时间

修复缺陷

3/28

1

讨论思路

阅读数据结构书

60min

描述:求一个二维数组中最大连通子数组的和时,没有达到目标要求

3/30

2

编码

编译

60min

描述:二维数组中最大连通子数组的和,由于使用动态规划做得,导致若有几行最大子数组相连时无法判断单个正数,所求最大连通子数组的和偏小,还有待解决

小伙伴在这里:http://home.cnblogs.com/u/wuyw/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: