序列和(sum)

Description

N个数排成一个环,请选出不超过K段的连续的数,段与段间不能重叠,且

使得选出的数和最大。

Input

 输入文件sum.in第一行包含两个正整数N和k。

    接下来1行描述这N个数。

Output

    输出文件sum.out包含一个数,即要去的最大的和。

Sample Input

9 2
2 -1 2 -1 2 -4 1 -1 2

Sample Output

7

Data Constraint

Hint

    20%:K=1,N<=1000

    另外20%:K=1

    另外20%:N<=1000

    100%:K<=10,N<=100000

Source / Author: NOIP2012模拟10.9

题解:

设f[i][j][k][l]表示到i点选了j段了,k表示i点是否选择,l表示1点是否被选。

f[i][j][0] = max( f[i-1][j][0] , f[i-1][j][1]) + 0;

f[i][j][1] = max(f[i-1][j][1] , f[i-1][j-1][0]) + a[i];

至于f的最后一维,只能从上一位同样的状态得来(f[ ][ ][ ][1] = max(f[ ][ ][ ][ ][1] ,f[ ][ ][ ][ 1]) ; f[ ][ ][ ][0] = max(f[ ][ ][ ][ ][0] ,f[ ][ ][ ][ 0]) )

因此,要预处理f[1][][][]

#include<bits/stdc++.h>
#define N 100010
#define K 20
#define ll long long
#define inf 2147483647
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;


ll n,k,i,j,l,ans,tmp;
ll f[N][K][2][2],a[N],sum[N],maxx[N];

int main()
{
    open("circle");
    scanf("%lld%lld",&n,&k);
    for(i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    memset(f,128,sizeof(f));
    f[1][0][0][0]=0;
    f[1][1][1][1]=a[1];
    for(i=n;i>0;i--)sum[i] = sum[i+1] + a[i];
    for(i=n;i>0;i--)maxx[i] = max(sum[i] , maxx[i+1]);
    for(i=2;i<=n;i++)
    {
//        for(j=1;j<=k+1;j++)
        for(j=1;j<=k;j++)
        {    
            for(l=0;l<2;l++)
            {
                if(f[i-1][j][0][l]>=0 &&  f[i-1][j][1][l]>=0)f[i][j][0][l] = max(f[i-1][j][0][l] , f[i-1][j][1][l]);
                 else if(f[i-1][j][0][l]>=0)f[i][j][0][l] = f[i-1][j][0][l]; else if (f[i-1][j][1][l]>=0) f[i][j][0][l]=f[i-1][j][1][l];
                if(f[i-1][j][1][l]>=0 &&  f[i-1][j-1][0][l]>=0)f[i][j][1][l] = max(f[i-1][j][1][l] , f[i-1][j-1][0][l]) + a[i];
                 else if(f[i-1][j][1][l]>=0)f[i][j][1][l] = f[i-1][j][1][l]+a[i]; else if(f[i-1][j-1][0][l]>=0)f[i][j][1][l] = f[i-1][j-1][0][l] + a[i];
//                if(j!=k+1)    
                if(l==1) tmp= maxx[i+1]; else tmp=0;
                ans = max(ans , max(f[i][j][0][l],f[i][j][1][l])+tmp);
            
            }
        }
    }
//    ans =  max(ans , f[n][k+1][1][1]);
    printf("%lld",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Com_man_der/article/details/88854213
今日推荐