B. Array Walk

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
",i,j,i,j,dp[i][j],i-1,j+1,dp[i-1][j+1],ans);
            }
        }
        printf("%lld
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/EchoZQN/p/13402050.html