• 子数组最大值设计02


    设计思路:

    才过几天就有了新挑战,我真是找不到多少时间看数学了,下面是新任务的大致意思:

    输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和,如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],…… A[n-1]A[0]……A[j-1]之和最大,求最大子数组的和最大子数组的位置。

    刚开始看这道题,看的我云里雾里的,觉得是看懂了,又感到有些迷惑,所以就简单把数组看成环形,然后想只要循环两圈不就解决了吗!so我开始如下的解题过程

    求解过程:

    这是上次的解题思路:

    数组形式:a[0],a[1],a[2],a[3]........a[n-1],a[n]

    总共可以看成求子过程最优,共两种情况:

    b[]=max(a[0]+a[1]+...a[i-1])看成到i元素的(i-1)子数组最大值

    If(b[]<0)这样a[i]+b[]<a[i] 则最大换为a[i]

    If(b[]>=0)a[i]+b[]>a[i] 最大换为a[i]+b[]

    基础上记入头尾然后再循环一次,结束位置在第一次结束的元素之前一个元素。

     

    如下是第一次考虑的错误代码(请不要直接复制):

     1 //实现数组的首尾相连 再求子数组的和最大值以及子数组的位置
     2 #include<iostream>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     /*求子数组的和
     8     输入整形数组,数组里有正数有负数,连续数字构成子数组
     9     求子数组最大值O(n)
    10     */
    11     //解题用动态规划求最优子结构
    12 
    13     cout<<"请输入数组元素个数:"<<endl;
    14     int num;  //数组元素个数
    15     cin>>num;
    16     int a[100]={0}; 
    17     for(int i=0;i<num;i++)
    18         cin>>a[i];    //输入数组元素
    19 
    20     //考虑首尾相连时改变数组结束判断的位置
    21 
    22     //动态求解
    23     int b[100][100]={0};
    24     b[0][0]=0;      //初始子数组和
    25     b[0][1]=a[0];    //a[i]数的值
    26     for(int i=1;i<num;i++)
    27     {
    28         if(b[i-1][0]>=0)
    29             b[i][0]=b[i-1][0]+b[i-1][1];
    30         else
    31             b[i][0]=b[i-1][1];
    32         b[i][1]=a[i];
    33     }
    34     //加上最后一个数(第一次迭代的结果)
    35     if(b[num-1][0]>=0)
    36         b[num][0]=b[num-1][0]+b[num-1][1];
    37     else
    38         b[num][0]=b[num-1][1];
    39     b[num][1]=a[0];     //循环(首尾连)
    40 
    41     //二次迭代
    42     for(int i=1;i<num;i++)
    43     {
    44         if(b[num+i-1][0]>=0)
    45             b[num+i][0]=b[num+i-1][0]+b[num+i-1][1];
    46         else
    47              b[num+i][0]=b[num+i-1][1];
    48         b[num+i][1]=a[i];
    49 
    50     }
    51     //比较各个子数组最大的求出值
    52     int max=b[0][0];
    53     for(int i=1;i<=(num+num-1);i++)
    54     {
    55         if(b[i][0]>max)
    56             max=b[i][0];
    57     }
    58     cout<<"子数组和最大值为:"<<max<<endl;
    59     return 0;
    60 }

    可能大家看到这就感觉有问题了,我也感觉有问题,但是说不上,但举个例子就明白了,

    -12结果是但答案肯定是5,因为在循环过程中重复使用数组元素,所以这样的算法有问题,得换个思维:

    其实这个循环过程就是每次nun个数的求解

    所以把上述的数组看成-1 2 3 -1 2,看到这大家的思路肯定更清醒了,只要依次求解每次循环中子数组最大,再比较就好了

    如下为正确代码:

      1 //实现数组的首尾相连 再求子数组的和最大值以及子数组的位置
      2 #include<iostream>
      3 #include<queue>
      4 #include<string>
      5 #include<sstream>
      6 using namespace std;
      7 
      8 int main()
      9 {
     10     /*求子数组的和
     11     输入整形数组,数组里有正数有负数,连续数字构成子数组
     12     求子数组最大值O(n)
     13     */
     14     //解题用动态规划求最优子结构
     15 
     16     queue<int> q=queue<int>();    //建立队列来循环数组
     17     string k[100][100];    //记录子数组最大位置
     18     cout<<"请输入数组元素个数:"<<endl;
     19     int num;  //数组元素个数
     20     cin>>num;
     21     int a[100]={0}; 
     22     int i=0,j=0;
     23     cout<<"请输入数组元素:"<<endl;
     24     for(i=0;i<num;i++)
     25         cin>>a[i];    //输入数组元素
     26 
     27     //考虑首尾相连时改变数组结束判断的位置
     28     //将n-1个数组元素放到数组尾部形成新数组
     29 
     30     for(j=0;j<num-1;j++)
     31     {
     32         q.push(a[j]);
     33     }
     34     for(j=0;j<num-1;j++)
     35     {
     36         a[num+j]=q.front();
     37         q.pop();
     38     }
     39     
     40     
     41     //动态数组求解
     42     int b[100][100][2]={0};
     43     i=0;j=0;
     44     for(i=0;i<num;i++)
     45     {
     46         b[i][0][0]=0;      //初始子数组和
     47         b[i][0][1]=a[i];    //a[i]数的值
     48         k[i][0]="";
     49         for(j=1;j<num;j++)
     50         {
     51           stringstream ss;
     52         if(b[i][j-1][0]>=0)     
     53         {
     54             
     55             b[i][j][0]=b[i][j-1][0]+b[i][j-1][1];
     56             ss<<((i+j-1)%num);
     57             ss>>k[i][j];      //写入位置字符数组
     58 
     59             k[i][j]=k[i][j-1]+k[i][j];
     60         }
     61         else
     62         {
     63             b[i][j][0]=b[i][j-1][1];
     64             ss<<((i+j-1)%num);
     65             ss>>k[i][j];    
     66             
     67         }
     68 
     69         b[i][j][1]=a[i+j];
     70         }
     71         stringstream ss;
     72         //加上最后一个数
     73     if(b[i][num-1][0]>=0)
     74     {
     75         b[i][num][0]=b[i][num-1][0]+b[i][num-1][1];
     76         ss<<((i+j-1)%num);
     77         ss>>k[i][num];
     78         k[i][num]=k[i][num-1]+k[i][num];
     79     }
     80     else
     81     {
     82         b[i][num][0]=b[i][num-1][1];
     83         ss<<((i+j-1)%num);
     84         ss>>k[i][num];
     85     }
     86 
     87     }
     88     
     89 
     90     //比较各个子数组最大的求出值
     91     int max=b[0][0][0];
     92     int max_i=0;   //记录最大值的坐标
     93     int max_j=0;
     94     for(i=0;i<num;i++)
     95     {
     96         for(j=0;j<=num;j++)
     97         {
     98         if(b[i][j][0]>max)
     99         {
    100             max=b[i][j][0];  
    101             max_i=i;
    102             max_j=j;
    103         }
    104         }
    105     }
    106     cout<<"子数组和最大值为:"<<max<<endl;
    107 
    108     int si=0,sl=0;
    109     cout<<"最大子数组各元素数组中的位置为(以0开始):";
    110     if(k[max_i][max_j].size()==1)
    111             cout<<k[max_i][max_j]<<endl;
    112     else
    113     {
    114         si=k[max_i][max_j].size();
    115         while(si--)
    116         {
    117             cout<<k[max_i][max_j][sl++]<<" ";
    118         }
    119     }
    120     cout<<endl;
    121         return 0;
    122 }

     运行代码:

    求解总结

    看问题必须要通过一些实例的验证才能确保是正确无误后,才能正确入手,保证结果正确性。

    最后附上工作照:

    Ps:同组的另一战友的博客

    http://www.cnblogs.com/brucekun/p/5321247.html

        每日一小步,月过一大步~~加油

  • 相关阅读:
    SVM高斯核为何会将特征映射到无穷维?【转载】
    sklearn.svm.LinearSVC文档学习
    NgDL:第四周深层神经网络
    Py中的矩阵乘法【转载】
    NN中BP推导及w不能初始化为0
    L2-006 树的遍历
    P3144 关闭农场 并查集 反向
    P1197 [JSOI2008]星球大战 并查集 反向
    P2700 逐个击破 最小生成树
    L2-005 集合相似度
  • 原文地址:https://www.cnblogs.com/ly199553/p/5322647.html
Copyright © 2020-2023  润新知