vijos1570(最大子段和变形)

来源:互联网 发布:北京知豆商标代理 编辑:程序博客网 时间:2024/06/08 16:39

链接:点击打开链接

题意:小新最喜欢的运动就是睡觉了,因为睡眠是精力恢复的重要保证。每次小新睡醒,他的脑海里总会浮现出一些奇怪的想法。某天醒来,他突然想到一个问题:对于一个长度为N的整数序列:A[1],A[2],...,A[N]。如果我们定义它的一个长度为M的K邻子序列为:A[P1],A[P2],...,A[PM];其中满足1<=K<N,1<=P1<P2<...<PM<N且P2-P1=P3-P2=...=PM-P(M-1)=K(注意,M=1,即子序列只包含一个数时,也认为它是一个合法的K邻子序列)。S(K)表示给定序列中的一个和最大的K邻子序列的和。小新想知道这些S(1),S(2),...,S(N-1)中的最大值是多少,你可以帮他回答这个问题么?(序列的和为一个序列中所有数的总和。)

代码:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;int a[10005],dp[10005];int main(){    int n,i,j,ans1,ans2,tmp;    while(scanf("%d",&n)!=EOF){                 //最大连续子段和变形        for(i=1;i<=n;i++)        scanf("%d",&a[i]);        ans1=ans2=-INF;        for(i=1;i<n;i++){            tmp=-INF;            memset(dp,0,sizeof(dp));            for(j=1;j<=n;j++){                  //要注意长度是1的时候可以满足任意k            dp[j]=a[j];            tmp=max(tmp,a[j]);            }            for(j=i+1;j<=n;j++){                //用最大子段和做                dp[j]=max(dp[j],dp[j-i]+a[j]);                tmp=max(tmp,dp[j]);            }            if(tmp>ans1){                ans1=tmp;                ans2=i;            }        }        printf("%d %d\n",ans1,ans2);    }    return 0;}

0 0