zoukankan      html  css  js  c++  java
  • 最大连通子数组求和

    //求最大联通子数组和 张鹏宇 武于微
    /****************************************************************
    题目要求:
    文件读入二维数组,计算最大联通子数组的和

    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/

  • 相关阅读:
    SQL Server的全局变量
    SQL局部变量
    视图和表之间的区别和联系
    SQL Server中开发常用的数据类型
    Bootstrap 字体图标、下拉菜单、按钮组
    Bootstrap 按钮,图片,辅助类
    Bootstrap表单
    Bootstrap表格
    Bootstrap排版类
    Bootstrap网格系统
  • 原文地址:https://www.cnblogs.com/fooreveryu/p/5360161.html
Copyright © 2011-2022 走看看