HDU-1003 Max sum

A - Max Sum

 
简单DP题主要就一思路,代码很好实现

思路;

(1)要记录开头和结尾,那么就开一个结构体,用来储存当前最大值和开头位置和结束位置

(2)判断 如果加的数 temp 大于 temp 和前面的最大值 (即新加的数temp自己单独更大,而前面的最大值为负)刷新开头和结尾 

(3)如果加的temp为正,而前面的最大值正(保证不与上面情况重复),那么说明,加上temp一定最大值一定会变大,结尾加1

下面AC代码

#include<stdio.h>
#include<string.h>
int a[100000];
int main()
{
    int t,step=0;
    scanf("%d",&t);
    while(t--)
    {
        int n,low=1,high=1,pos1=1,pos2=1;
        step++;
        if(step!=1)
        {
            printf("\n");
        }
        scanf("%d",&n);
        memset(a,0,sizeof(a));
        a[0]=-1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int max=a[1],temp=a[1];
        for(int i=2;i<=n;i++)
        {
            if(a[i]>a[i]+temp)
            {
                temp=a[i];
                low=i;
                high=i;
            }
            else
            {
                temp+=a[i];
                high++;
            }
            if(temp>max)
            {
                max=temp;
                pos1=low;
                pos2=high;
            }
        }
        printf("Case %d:\n%d %d %d\n",step,max,pos1,pos2);
    }
    return 0;
}
在网上,我找到一个大神代码,和我思路一样,但是比我这简单明了

大神代码的变量有点多,我先介绍一下

t	        测试数据组数
n	        每组数据的长度
temp	        当前取的数据
pos1  	最后MAX SUM的起始位置
pos2	        最后MAX SUM的结束位置
max		当前得到的MAX SUM
now		在读入数据时,能够达到的最大和
x		记录最大和的起始位置,因为不知道跟之前的max值的大小比,所以先存起来

#include <iostream>  
using namespace std;  
  
int main()  
{  
    int t,n,temp,pos1,pos2,max,now,x,i,j;  
    cin>>t;  
    for (i=1;i<=t;i++)  
    {  
        cin>>n>>temp;  
        now=max=temp;  
        pos1=pos2=x=1;  
        for (j=2;j<=n;j++)  
        {  
            cin>>temp;  
            if (now+temp<temp)  
                now=temp,x=j;  
            else  
                now+=temp;  
            if (now>max)  
                max=now,pos1=x,pos2=j;  
        }  
        cout<<"Case "<<i<<":"<<endl<<max<<" "<<pos1<<" "<<pos2<<endl;  
        if (i!=t)  
            cout<<endl;  
    }  
    return 0;  
}  

只有这短短几行,比我少一半

我好菜啊!

分析一下大神代码优点

大神把输入和过程中的循环合并了(我的是先输入,再进行过程,二者完全分开)

大神定义变量集中定义的,而我是想起来,随便找个地方补一下,或者变量不够了,再补

这样的代码很乱,没有什么可读性,下次注意


再说说思路;

刚开始我并没有想出来,

下面我来总结一下,下次遇到类似题应该如何想,如何找思路

(1)一般来说,动规过后出现都是最优解

但是这题不是,动规后的结果可能是最优解,也可能不是

这时候需要我们开个变量来储存这个最优解

(2)因为这子链是连续的,那我们肯定要判断一下这个链是否在那里断开从新开一个新的链

如果不开新链,那我们就一直加,找最优情况,存起来


当时我一直的思路是;

普通DP,每次DP找最优解,但是根本就没法找,

难道要每加一个数,搜索一下?


其实这个思路是挺不好想的,




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值