最大连通子数组求和
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 | ||
描述:二维数组中最大连通子数组的和,由于使用动态规划做得,导致若有几行最大子数组相连时无法判断单个正数,所求最大连通子数组的和偏小,还有待解决 |
相关文章推荐
- hdu 4123 树形dp+rmq
- Log4J日志配置详解
- 团队加分作业
- 在Eclipse中配置Teamcenter二次开发环境时候debug,Tteamcenter不能正常登录
- LeetCode *** 136. Single Number
- LeetCode [Symmetric Tree]
- mysql 一行数据+标题转换为两列
- Nodejs Error: Cannot find module 'unicode/category/So'
- Kali Linux
- .价值观作业
- 数据结构中的栈
- 使用Redis的理由
- uva 558 Wormholes
- MyEclipse控制台中文输出乱码
- 使用ViewPager加载页面出现空白--笔记
- mysql merge table
- no field package.preload[‘ffi’]
- ASP.NET MVC Model绑定(四)
- 可以打开mdb文件的小软件
- mysql merge table