题目分析
首先,这道题比较的简单,是一道较为标准的 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();
}
}
标签:int,题解,leq,text,ans,dp,CF1389B
From: https://www.cnblogs.com/bairixingchen/p/16653037.html