hdu 1003 Max Sum

本文分享了一位编程新手使用动态规划解决最大子序列和问题的经历,通过对比两种不同实现方法,展示了如何从超时到通过挑战的过程。

 题意;给你一个数组,让你找和最大的子序列,输出子序列的最大和,和子序列两端的位置。

由于这是我dp开始的第一题,我用了最淳朴的dp,结局当然是超时。

这是超时代码,但是我觉得这个代码真心体现了dp思想,可以给初学者了解dp用

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a1[10005],dp[10005][10005];
int main()
{
   int t,n,i,j,sum,a,b,k;
   cin>>t;
  for(k=1;k<=t;k++)
   {
     cin>>n;
     sum=0;
     for(i=1;i<=n;i++)
        cin>>a1[i];
     memset(dp,0,sizeof(dp));
     for(i=1;i<=n;i++)
     {
        for(j=i+1;j<=n;j++)
        {
           if(j==i+1)     //可以自己画个二维坐标试  就明白了

                dp[i][j]=a1[i]+a1[j];
                if(dp[i][j]>sum)
                {
                  sum=dp[i][j];
                  a=i;
                  b=j;
                }


           }
           else
           {
               dp[i][j]=dp[i][j-1]+a1[j];
               if(dp[i][j]>sum)
               {
                  sum=dp[i][j];
                  a=i;
                  b=j;
               }


           }
        }
     }
     printf("Case %d:\n",k);
     printf("%d %d %d\n",sum,a,b);


   }
}

然后就看看别人高大上的解法  自己写的 改了无数遍 最终AC



#include<iostream>
#include<cstring>
#include<cstdio>
#define N 100010    //一开始超时  用了宏定义之后  就不超了
using namespace std;
int d[N],a1[N];
int main()
{
  int t,n,Max,a,b,i,j,m;
scanf("%d",&t);
  for(j=1;j<=t;j++)
  {
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d",&a1[i]);
    d[1]=a1[1];
   Max=d[1];  //第一个数自己最大时的特殊情况
   b=1;
    for(i=2;i<=n;i++)
    {
      if(d[i-1]<0)
         d[i]=a1[i];
      else
        d[i]=d[i-1]+a1[i];
      if(Max<d[i])
        {
          Max=d[i];
          b=i;
        }
    }
    int f=0;
    for(i=b;i>0;i--)
    {
        f+=a1[i];
      if(f==Max)
            a=i;
    }
     printf("Case %d:\n",j);
     if(j!=t)
      printf("%d %d %d\n\n",Max,a,b); //看清楚给的样例
     else
      printf("%d %d %d\n",Max,a,b);
  }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值