数学考试dp
发布日期:2021-05-07 16:48:41 浏览次数:22 分类:技术文章

本文共 1217 字,大约阅读时间需要 4 分钟。

来自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<
<

用一个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存和最大的情况,输出。

上一篇:吐泡泡(栈)
下一篇:紫书——蛇形填数

发表评论

最新留言

表示我来过!
[***.240.166.169]2025年04月13日 18时29分02秒