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\n",i,j,i,j,dp[i][j],i-1,j+1,dp[i-1][j+1],ans);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
posted @ 2020-07-30 09:46  EchoZQN  阅读(221)  评论(0编辑  收藏  举报