数学考试dp

来自https://ac.nowcoder.com/acm/problem/15553

先是read()函数,用于快速读入,比cin快,比printf快

int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-'){
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

调用函数的时候定义一个新变量
比如输入一个T,表示测试次数

int T;
T=read();

接下来是看题干,两个不连续的区间
区间长度为k

int main(){
    ll t,a;
    ll ans[200005];
    ll sum[200005];
    cin>>t;
    memset(ans,-0x7f,sizeof(ans));//0x7f??
    memset(sum,0,sizeof(sum));
    while(t--){
        ll n,k,res=-1e18;
        n=read();k=read();
        for(int i=1;i<=n;i++){
            a=read();
            sum[i]=sum[i-1]+a;
        }
        for(int i=n-k+1;i>k;i--){
            ans[i]=max(ans[i+1],sum[i+k-1]-sum[i-1]);
            res=max(res,ans[i]+sum[i-1]-sum[i-k-1]);
        }
        cout<<res<<endl;
    }
    return 0;
}

用一个sum[i]表示前i个数的和,这样区间[l,r]可以用sum[r-1]-sum[l-1]表示。
这种开数组的做法避免了遍历ai求和的过程(优化)。
然后自右向左,比较[i,k]的区间中的成绩和,取最大的存入ans[i]中,定义一个res为最后结果,取i左边最大的区间和右边最大的区间和。
右边最大的区间为ans[i] (sum[i+k-1] - sum[i-1]) ,左面最大的为sum[i-1] - sum[i-k-1].
再解释一下,就是ans[i]的部分在通过遍历寻找右面区间的最大值,然后如果有更大的就顶替掉原来的ans[i],不然就ans[i]=ans[i+1]继续保持最大结果。i左边的区间同理。最后用res存和最大的情况,输出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值