zoukankan      html  css  js  c++  java
  • HDU 1231 最大连续子序列

    状态表示:dp[i]是必须以A[i]结尾的连续序列。

    那么只有两种情况:

    1. 这个最大和的连续序列只有一个元素,即以A[i]开始,以A[i]结尾。
    2. 这个最大和的连续序列有多个元素,即从前面某处A[p]开始(p<i),一直到A[i]结尾。

    对第一种情况,最大和就是A[i]本身。
    对第二种情况,最大和是dp[i- 1]+A[i],即A[p] +...+ A[i- 1]+ A[i]= dp[i- 1] + A[i]。

    由于只有这两种情况,于是得到状态转移方程:

    [dp[i] = max(A[i],dp[i-1]+A[i]) ]

    这个式子只和i与i之前的元素有关,且边界为dp[0]= A[0],由此从小到大枚举i,即可得到整个dp数组。接着输出dp[0], dp[1],... , dp[n - 1]中的最大值即为最大连续子序列的和。

    除了需要求出最大连续子序列的值外还需要输出最大连续子序列的第一个和最后一个元素。

    用两个变量from和to记录循环到以第(i)个元素结尾的最大连续子序列时的左、右元素,from和to伴随着(i)的右移进行迭代更新。

    若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。

    const int N=10010;
    int a[N];
    int f[N];
    int n;
    
    int main()
    {
        while(cin>>n, n)
        {
            for(int i=0;i<n;i++) cin>>a[i];
    
            f[0]=a[0];
            int ans=a[0];
            int from=a[0],to=a[0];
            int ansl=a[0],ansr=a[0];
            for(int i=1;i<n;i++)
            {
                if(f[i-1]+a[i] > a[i])
                {
                    f[i]=f[i-1]+a[i];
                    to=a[i];
                }
                else
                {
                    f[i]=a[i];
                    from=to=a[i];
                }
                if(f[i] > ans)
                {
                    ans=f[i];
                    ansl=from;
                    ansr=to;
                }
            }
            
            if(ans < 0) cout<<0<<' '<<a[0]<<' '<<a[n-1]<<endl;
            else cout<<ans<<' '<<ansl<<' '<<ansr<<endl;
        }
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    WPF学习笔记(三)
    WPF自定义控件——使用Win32控件
    WPF学习笔记(二)
    WPF自定义控件 —— 装饰器
    WPF中改进自定义Command一些想法
    WPF自定义控件 —— 布局
    制作WPF联机飞行棋的失败体验
    WPF自定义控件 —— 自绘篇
    c语言清屏、等待、随机函数
    c语言一个显示星号的函数(隐藏密码)
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14358641.html
Copyright © 2011-2022 走看看