首页 > 其他 > 详细

(某种)数列问题

时间:2019-11-04 21:42:37      阅读:95      评论:0      收藏:0      [点我收藏+]

【题目描述】

  给定一个长度为 n 的整数序列,可能存在负数,从中找到 3 个无交集的连续 子数列使其和最大。一个元素不能被编入多个序列而且一定要拿出 3 个序列。 简单滴说就是: 给定一个数列,从中找到 3 个无交集的连续子数列使其和最大。

【输入文件】

  第一行一个数 n,表示数列长度。

  接下来有 n 行,每行一个数,第 i 行为第 i 个数。

【输出文件】

  仅有一个数,表示最大和。

【样例输入】

   10 -1 2 3 -4 0 1 -6 -1 1 -2

【样例输出】

   7

【样例说明】

   第一个序列取 2,3。

   第二个序列取 0,1。

   第三个序列取 1。

【数据范围】

   对于 30%的数据,n<=200。 对于 60%的数据,n<=2000。 对于 100%的数据 n<=1000000。 答案不超过 maxlongint。

 

   模拟赛的题目,一开始知道是动规,但是完全懵逼,上网查了之后才发现是【某种数列问题】(题目名,真的连样例都没改,可以自己上网查)。

  

    核心思路

     设定一个数组f,约定f[i][j][k](0<=i<=n,0<=j<=3,k=1或0)为在第i个位置时,把前面i-1个数分成j组,当k=1时取第i个数,k=0则不取。这时考

      虑状态转移方程,当前的数有两种选择,

      取或不取。

     第一种情况

     不取,那么第i-1个数有可能取也有可能不取。显然两种情况jC:\Users\ASUS\Desktop的值转移时都不会改变,所以易得转移方程:

                                  技术分享图片

     第二种情况

   取,那么第i-1个数同样也有两种选择。取的时候,又可以分成两种情况:1.从第i个数开始为新的一组数;2.第i个数与第i-1个数为同一组。    不取,那么第i个数肯一 

   组新的数,所以得转移方程:

                                  技术分享图片

  代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1000010;//打常数是个好习惯 
int n;
int ans,a[MAXN],f[MAXN][4][2];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    memset(f,-127,sizeof(f));
    f[0][0][0]=0;//初始化 
    for(int i=1;i<=n;++i)
        for(int j=0;j<=3;++j){
            f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]);//当前数不取 
            if(j) f[i][j][1]=max(f[i-1][j-1][0]+a[i],f[i-1][j-1][1]+a[i]);
            f[i][j][1]=max(f[i][j][1],f[i-1][j][1]+a[i]);//当前数取 
        }
    printf("%d",max(f[n][3][0],f[n][3][1])); 
    return 0;
}

 

(某种)数列问题

原文:https://www.cnblogs.com/Ymyself/p/11794488.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!