数学考试dp解法

数学考试

http://www.nowcoder.com/questionTerminal/e1e3e65479114efb9c68b1fe7db11b34

题目大意:

有一个长度为n的数列,要求在这个数列中选2个不相交且长度都为k的区间,求这两个区间中数字和最大的值

算法过程

A[i]表示长度为k且以i为最后一个元素的这个区间元素值的和
dp[i]表示选择的第二个区间以第i个元素结尾所求和的最大值
维护一个tmp,表示在前i-k个元素中长度为k的区间和最大值
那么状态转移方程为

dp[i]=tmp+A[i]

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> P;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f;
const int MAX_N=2e5+20;
const LL MOD=1e9+7;
int n,k;
LL a[MAX_N];
LL A[MAX_N];//A[i]表示长度为k且以i为最后一个元素的这个区间元素值的和
LL dp[MAX_N];
int T;
int main(){
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        LL sum=0;
        for(int i=1;i<=k-1;i++){
            A[i]=-1;
            sum+=a[i];
        }
        for(int i=k;i<=n;i++){
            sum+=a[i];
            A[i]=sum;
            sum-=a[i-k+1];
        }
        LL tmp=A[k];
        LL ans=-LINF;//注意可能是负值
        for(int i=2*k;i<=n;i++){
            dp[i]=A[i]+tmp;
            tmp=max(tmp,A[i-k+1]);
            ans=max(dp[i],ans);
        }
        printf("%lld\n",ans);
    }
}

全部评论

相关推荐

08-10 12:43
临沂大学 Java
等闲_:1,换一个模版,这个模版没有人会看的 2,项目太烂大街了,也太简单了,找AI优化一下描述,项目可以烂大街,但是简历不能烂大街,或者找项目换一下 3,如果没什么奖的话,把学校放到下面,添加一个个人描述,简单些,让简历丰富一些 4,改完之后海投试试,但是我真的很建议别走java了,可以试试前端
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务