• 最大联通子数组


    程序设计思路:

        求一个二维数组中的最大联通子数组,第一步需要做的就是将一个二位数组转化成图的形式,根据题目的要求可以,每一行每一列的相互紧邻的元素都是联通的,而处于对角线位置的运算则不是相互联通的,另外,前一行的最后一个元素与下一行的第一个元素也不是联通的。为表示数组元素之间的关联程度采用一个二位数组Relation来表示,若元素存在关联关系,则数组中存入1;后续的工作就是遍历,同样采用动态规划的思想去完成,只不过需要多次遍历。题目中要求从一个文件中读入数组的行数列数和元素,因此,在运算之前要写一个函数从文件中读入,暂存到数组和变量中。

    程序源代码:

    //返回一个二维整数数组中最大联通子数组的和
    //2016-04-01
    
    #include<iostream>
    #include<fstream>
    using namespace std;
    
    //从文件中读取数组到内存中
    void ReanformFile(int &row, int &col, int E[])
    {
        ifstream infile;
        infile.open("input.txt", ios::in | ios::_Nocreate);   //打开当前目录下的txt文档
        if (!infile)
        {
            cerr << "open error!" << endl;
        }
        infile >> row >> col;
        for (int i = 1; i < (row*col + 1); i++)
        {
            infile >> E[i];            //将文件中的元素存放到一个一维数组中
        }
        infile.close();
    }
    
    //记录二维数组中每个元素与其他元素之间的联系,若相紧邻,则将二维数组中的元素值设置为1,处于对角线位置的元素没有关联关系
    void outputElement(int row, int col, int E[], int R[][100])
    {
        for (int i = 1; i <(row*col + 1); i = i + col)
        {
            for (int j = i; j <= i + col - 2; j++)
            {
                R[j][j + 1] = 1;
                R[j + 1][j] = 1;
            }
        }
        for (int i = 1 + col; i<(row*col); i = i + col)
        {
            for (int j = i; j <= i + row - 1; j++)
            {
                R[j][j - col] = 1;
                R[j - col][j] = 1;
            }
        }
        //以二位数组的形式输出文档中的元素值
        for (int i = 1; i <= (row*col); i++)
        {
            cout << E[i];
            if (R[i][i + 1] == 1)
                cout << "  ";
            else
                cout << endl;
        }
    }
    
    //查找某个元素周围的元素是否可以加入到最大联通子数组中
    void Select(int row, int col, int E[], int R[][100], int v, int visit[], int &max, int &temp)
    {
        visit[v] = 1;
        max = max + E[v];
        if (max >= temp)
        {
            temp = max;
        }
        int m = 0, n = 0;
        for (int i = 1; i <= (row*col); i++)
        {
            for (int j = 1; j <= (row*col); j++)
            {
                if ((visit[i] == 0) && (R[j][i] == 1) && (visit[j] == 1))
                {
                    m = i;
                    n = 1;
                    break;
                }
            }
            if (n == 1) break;
        }
        for (int i = 1; i <= (row*col); i++)   //查找是否存在比该元素更大的元素
        {
            for (int j = 1; j <= (row*col); j++)
            {
                if ((visit[i] == 0) && (R[j][i] == 1) && (visit[j] == 1))
                {
                    if (E[m] < E[i])
                    {
                        m = i;
                    }
                }
            }
        }
        if (temp + E[m] < 0)
        {
            R[v][m] = 0;
        }
        else
            Select(row, col, E, R, m, visit, max, temp);
    }
    
    int main()
    {
        int row = 0, col = 0;  //存储行数和列数
        int Element[100];    //存储每个元素的值
        int Relation[100][100];
        int v = 1, temp[100] = { 0 };
        ReanformFile(row, col, Element);
        outputElement(row, col, Element, Relation);
        for (int i = 1; i <= (row*col); i++)
        {
            if (Element[i]<0)
            {
                temp[i] = Element[i];
            }
            else
            {
                int max = 0;
                int visit[100] = { 0 };
                Select(row, col, Element, Relation, i, visit, max, temp[i]);
            }
        }
        int max = temp[1];
        for (int i = 2; i <= (row*col); i++)
        {
            if (temp[i] > max)
            {
                max = temp[i];
            }
        }
        cout << "最大子数组的和为:" << max << endl;
        return 0;
    }

    运行结果截图:

  • 相关阅读:
    用kettle做ETL时设置mysql连接参数使数据写入速度加快
    infobright社区版rpm包
    mysql在大数据量下性能调优相关参数
    greenplum给某个用户赋予整个schema下所有表的权限
    Linux挂载大于2T的磁盘硬盘
    Centos 系统swap(虚拟内存)管理
    域内
    随便记录一些东西
    有关终端的一些tips
    精悍的指令
  • 原文地址:https://www.cnblogs.com/hulidanxiang/p/5360130.html
Copyright © 2020-2023  润新知