HDOJ1003最大和子数组(动态规划)

http://acm.hdu.edu.cn/showproblem.php?pid=1003

题目大意:输入T为总的案例数,每个案例中首先输入N表示数组长度,随后输入N个数a[1]-a[N]表示一个数组,求一个子数组,要求这个子数组所有数加起来和最大,并输出这个子数组的起始下标,如果有多个子数组都是和最大的,则输出第一个满足条件的子数组的下标。

考虑前N个元素(数组所有元素),设f[N]为从前N个元素选择,最大子数组的和。则求前N个元素的最大子数组,有两种情况:1、最大子数组不包含a[N],此时前N个元素的最大子数组为前N-1个元素的最大子数组f[N-1]。2、最大子数组以a[N]结尾,设g[N]表示以a[N]结尾的最大子数组的和。以a[N]结尾最大子数组,要么是a[N]自己本身,要么是以a[N-1]结尾的最大子数组,要么是a[N]自己,所以确立递推关系g[N]=max{ a[N],g[N-1]+a[N] }。总的递推关系:f[N]=max{ g[N] , f[N-1] }。

这里还有一个问题,需要输出最大子数组的起始下标,我们引入了两组变量:tmpstart、tmpend和preleft、preright,两组变量的定义已经写在了注释当中。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
//#define DEBUG
void solve(int *left,int *right);


int T;
int N;
int a[100005];
int f[100005],g[100005];
int main(){
    cin>>T;
    int left,right;
    for(int i=1;i<=T;i++){
        cin>>N;
        for(int j=1;j<=N;j++) cin>>a[j];//a[1]-a[N]为待求序列
        solve(&left,&right);
        cout<<"Case "<<i<<":"<<endl;
        cout<<f[N]<<" "<<left<<" "<<right<<endl;
        if(i!=T)  cout<<endl;
    }
}
void solve(int *left,int *right){
    int start,end;
    f[1]=a[1];
    g[1]=a[1];
    int tmpstart=1,tmpend=1;//求前i个元素的最大子数组的时候以第i个数字结尾的最大子序列左右两个下标
    int preleft=1,preright=1;//当求前i个数字的最大子数组的时候,这组变量表示前i-1个元素的最大子数组的两个下标
    for(int i=2;i<=N;i++){
        if(g[i-1]+a[i]>=a[i]){//当有多个子序列满足条件的时候输出第一个子序列的起止下标,所以这里有等号,这个等号是我通过实际的测试数据测试过后加上的
            tmpend=i;
            g[i]=g[i-1]+a[i];
        }else{
            tmpstart=tmpend=i;
            g[i]=a[i];
        }
        if(f[i-1]>=g[i]){
            f[i]=f[i-1];
            *left=preleft;
            *right=preright;
        }else{
            f[i]=g[i];
            *left=tmpstart;
            *right=tmpend;
        }
        //此时*left,*right为前i个元素最大子序列的起止下标
#ifdef DEBUG
    cout<<"i="<<i<<endl;
    cout<<"f["<<i-1<<"]="<<f[i-1]<<endl;
    cout<<"g["<<i<<"]="<<g[i]<<endl;
    cout<<"f["<<i<<"]="<<f[i]<<endl;
    cout<<"left="<<(*left)<<"right="<<(*right)<<endl;
#endif
        preleft=*left;
        preright=*right;
    }
}

猜你喜欢

转载自blog.csdn.net/LOVETEDA/article/details/83794777