【HDOJ】1003,反思及代码

来源:互联网 发布:淘宝卖家怎样设置运费 编辑:程序博客网 时间:2024/06/08 16:10

     刷题真是一个无比痛苦的过程。。。1003别人都说是水题,但是我断断续续做了3天才做出来,中间还多次参考别人的代码,真是郁闷,但是也学到了不少东西。

     首先是1003出现了算法上的技巧性,对于我这个没有学过啥算法的菜鸟来说,第一天做这题完全是无头苍蝇,先是暴力循环果断超时,然后看别人的代码发现他们说什么状态方程什么的就头大。

     第二天突然想明白大概的算法了,因为是连续数列的最大和,可以逐段考虑,如果之前那一段的和是负数,那么应当重新设置下一串数的起点(因为如果包括前一段的任意一部分的话,和会变小),重复这个过程,将得到的各个子列的和与最大值比较,如果大于先前的最大值则更新最大值和起点、终点。然后有想到了一个问题,如果之前那一串中有若干大正数,那么包括进去可能会更大,但是实际上,可以采用反证法:首先,此时前一串的和为负,如果包括从前一串的任意一点到结尾(也就是目前指针的位置)的一段,这一段为正值的话,那么该串更前面的那一段的和应当为负(因为总和为正),但是这违背了一串的和为负数时就抛弃的规则。这就说明了该规则是合适的。

     然后感觉更坑爹了,因为早先的思路大体正确,但是存放起点和终点的指针都是单一变量,这样虽然在输入较短的时候没有问题(我测试了好多遍才发现问题,之前固执的WA了好多次),但是一旦数据规模稍大就不对了,尤其是正数负数叉开的数据分布会出现问题。虽然这么说很不清楚,但是本题应该记录下所有子串的起点和终点才能正确输出,所以起点必须要开个数组保存。。。。

     然后是今天,感觉所有问题都解决了,但是stuck overflow.................搞不懂,以为是只有递归函数才会出现这种问题,查了半天才知道只要是定义在函数体内的变量都在栈区,所以把所有的数组全部放到开头。。。终于ACCEPT了。。。

    不容易啊,菜鸟好幸苦

——————————————————————————————————————

#include<iostream>
#define N 100100
using namespace std;
 int subsq[N];
int nums[N];
int tstart[N];
int main()
{
   int T,n,t=0;

   int tend,maxsum=-9999;

   cin>>T;
   while(T>0)
   {
       T--;
       t++;
       cin>>n;
       cin>>nums[0];

    tend=0;
    tstart[0]=0;
    maxsum=nums[0];
    subsq[0]=nums[0];
    for(int i=1;i<n;i++)
    {
        cin>>nums[i];
        if(subsq[i-1]<0)
            {
                tstart[i]=i;
                subsq[i]=nums[i];
            }
            else
            {
                tstart[i]=tstart[i-1];
                subsq[i]=subsq[i-1]+nums[i];

            }
            if(subsq[i]>maxsum)
                {
                    maxsum=subsq[i];
                    tend=i;
                }
    }
       cout<<"Case "<<t<<':'<<endl;
       cout<<maxsum<<' '<<tstart[tend]+1<<' '<<tend+1<<endl;
       if(T>0)
        cout<<endl;
   }
   return 0;
}

 

0 0
原创粉丝点击