連結: https://www.nowcoder.com/acm/contest/96/H
來源:牛客網
題目描述 今天qwb要參加一個數學考試,這套試卷一共有n道題,每道題qwb能獲得的分數為ai,qwb並不打算把這些題全做完,
他想選總共2k道題來做,並且期望他能獲得的分數儘可能的大,他準備選2個不連續的長度為k的區間,
即[L,L+1,L+2,....,L+k-1],[R,R+1,R+2,...,R+k-1](R >= L+k)。
輸入描述:
第一行一個整數T(T<=10),代表有T組資料接下來一行兩個整數n,k,(1<=n<=200,000),(1<=k,2k <= n)接下來一行n個整數a1,a2,...,an,(-100,000<=ai<=100,000)
輸出描述:
輸出一個整數,qwb能獲得的最大分數
題解:dp1[i],dp2[i+1]儲存從i切割後左右兩段所能取得的最大值。根據遞推式求出dp1,dp2後枚舉切點即可。代碼:#include<bits/stdc++.h>using namespace std;#define ll long longconst int maxn=200005;ll a[maxn],sum1[maxn],sum2[maxn],dp1[maxn],dp2[maxn];int main(){ int T;scanf("%d",&T); while(T--) { int n,k;scanf("%d%d",&n,&k); for(int i=0;i<=n+1;i++) dp1[i]=dp2[i]=-1e18; sum1[0]=sum2[n+1]=0; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); sum1[i]=sum1[i-1]+a[i]; if(i>k)sum1[i]-=a[i-k]; if(i==k)dp1[i]=sum1[i]; else dp1[i]=max(sum1[i],dp1[i-1]); } for(int i=n;i>=1;i--) { sum2[i]=sum2[i+1]+a[i]; if(n-i>=k)sum2[i]-=a[i+k]; if(n-i<k)dp2[i]=sum2[i]; else dp2[i]=max(dp2[i+1],sum2[i]); } ll ma=-1e18; for(int i=k;i+k<=n;i++) ma=max(dp1[i]+dp2[i+1],ma); printf("%lld\n",ma); } return 0;}