CF1389B题解

题目传送门

题目分析

首先,这道题比较的简单,是一道较为标准的 dp ,虽说有大佬说可以用贪心做,但本蒟蒻不会

首先, \(0 \leq z\leq \min(5,k)\) 所以我们可以开一个二维 dp ,其中有一位用来记录现在所到的位置 \(i\) 以及向右一共要走的步数 \(j\) ,由于可以向左或者是向右走。于是就可以想出 dp 转移方程式。

dp 转移方程式:

\(dp_{i,j} = \begin{cases} dp_{i-1,j}+a_i &\text{if } 1\leq i ,j\leq z\\ \max(dp_{i+1,j-1}+a_i,dp_{i-1,j}+a_i) &\text{if }j \ne 0,i\ne n \end{cases}\)

而当 \(i+2 \ast j=k\) 的时候,就要对 \(ans\) 的值进行更新,将其更新为 \(dp_{i,j}\)

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k,z;
int a[100001];
int dp[100001][10];
int ans;
void solve(){
	ans=0;
	cin>>n>>k>>z;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int j=0;j<=z;j++){
		for(int i=1;i<=n;i++){
			dp[i][j]=dp[i-1][j]+a[i];
			if(j&&i!=n){
				dp[i][j]=max(dp[i+1][j-1]+a[i],dp[i][j]);
			}
			if(i-1+j*2==k){
				ans=max(ans,dp[i][j]);
			}
		}
	}
	cout<<ans<<"\n";
}
signed main(){
	int T;
	cin>>T;
	while(T--){
		solve();
	}
}

posted @ 2022-09-03 16:59  IloveKodoli  阅读(109)  评论(0)    收藏  举报