HDU1003

咸鱼楼终于开始刷oj了,这个博客就当存题解了。

#include <iostream>

using namespace std;

int main()
{
    int n,N,i,j,dp,temp1; 
    int ct=0;
    int a[100001];
    cin>>N;
    while(N>0)
    {
        cin>>n;
        for(int k=0;k<n;k++)
         cin>>a[k];
        dp=a[0];
        temp1=dp;
        j=0;i=0; //第一次忘记初始化了,于是WA了
        for(int q=1;q<n;q++)
        {
           if(temp1>0) temp1=temp1+a[q];
           else temp1=a[q];
           if(temp1>=dp)
           {
               dp=temp1;
               j=q;
           }
        }
        temp1=0;
        for(int p=j;p>=0;p--)   //很奇葩的脑回路
        {
            temp1=temp1+a[p];
            if(temp1==dp)
                i=p;
        }
        ct++;
        cout<<"Case "<<ct<<":"<<endl;
        cout<<dp<<" "<<i+1<<" "<<j+1<<endl;
        if(N!=1) cout<<endl;
        N--;
    }
    return 0;
}

    这是最最普通的方法,另外一种常见的解法是分治+dp(上学期写过,然而忘记了)。大体思路是将数字串分为左右两部分,最大子序列和要么在左边,要么在右边,要么跨过边界。所以分情况讨论。
     另外在网上看到一个很厉害的解法,贴上来。侵删 点击打开链接
     
#include <iostream>  
#include <cstdio>  
#include <cstring>  
#include <algorithm>  
#include <queue>  
#include <vector>  
#define MAX 100007  
  
using namespace std;  
  
int lef,rig;  
int ans;  
int sum,loc;  
  
int main ( )  
{  
    int t,n,a;  
    scanf ( "%d" , &t );  
    int c = 1;  
    while ( t-- )  
    {  
        int ans = -99999999;  
        int minn = 99999999;  
        sum = 0;  
        scanf ( "%d" , &n );  
        for ( int i = 1 ; i <= n ; i++ )   
        {  
            scanf ( "%d" , &a );  
            sum += a;  
            if ( minn >= 0 )  
            {  
                if ( sum > ans ) ans = sum , lef = 1 , rig = i;  
            }  
            else if ( sum - minn > ans )  
                ans = sum -minn , lef = loc , rig = i;  
            if ( sum < minn) minn = sum ,loc = i+1;  
        }  
        printf ( "Case %d:\n" , c++ );  
        printf ( "%d %d %d\n" , ans , lef , rig );  
        if(t)  puts ( "" );  
    }  
}  

     

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值