B. Array Walk
这一场打的很不好,B题确实有点难度,但是应该不至于写不出来,可能当时紧张了,确实觉得自己最近打比赛心态有问题,太着急了。慢慢来吧。
这个就是一个dp,一开始也想的是dp,但是呢,写搓了,然后一直 wa ,就觉得不是dp了,最后发现其实是dp,是自己转移方程出现了问题。
对于 \(dp[i][j]\) 有两种转移:
- \(dp[i][j]=dp[i-1][j]+a[i]\)
- \(dp[i-1][j+1]=dp[i][j]+a[i-1]\)
第一个转移很好想,但是第二个呢,也不是很难,只是这样的写法非常少,就直接pass了。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 3e5+10;
ll dp[maxn][10],a[maxn];
//定义dp[i][q]是当前在索引i位置且往左走了q次的最大价值
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,k,z;
scanf("%d%d%d",&n,&k,&z);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=0;i<=n;i++) memset(dp[i],0,sizeof(dp[i]));
ll ans = 0;
dp[1][0]=a[1];
for(int i=2;i<=n;i++){
for(int j=0;j<=z;j++){
dp[i][j]=max(dp[i-1][j]+a[i],dp[i][j]);//直接从i-1转移过来
if(i-1+2*j==k) ans = max(ans,dp[i][j]);
//往回退一步
dp[i-1][j+1]=max(dp[i-1][j+1],dp[i][j]+a[i-1]);
if(i-1-1+2*(j+1)==k&&j+1<=z) ans = max(ans,dp[i-1][j+1]);
// printf("i=%d j=%d dp[%d][%d]=%lld dp[%d][%d]=%lld ans=%lld\n",i,j,i,j,dp[i][j],i-1,j+1,dp[i-1][j+1],ans);
}
}
printf("%lld\n",ans);
}
return 0;
}