解题思路
连续变换两个位置是不明智的选择。所以我们可以设计 d p [ i ] [ j ] [ 0 / 1 ] dp[i][j][0/1] dp[i][j][0/1] 的状态,其中第三维表示上一个位置是否被改变过,i 表示当前位置,j 表示之前已经变换过 j 次(要保证 j 时刻小于等于 k)。如果当前位置的 a [ i ] a[i] a[i] 已经是山谷点,则无需变换,否则可以考虑变换的转移方程,在 dp 过程中一直记录最大值即可。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,k,w,ww,a[2010];
ll ans,maxn,d[2010][2010][2];
int main() {
scanf("%d%d",&n,&k);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
ans=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=k;j++)
{
d[i][j][0]=max(d[i-1][j][1],d[i-1][j][0]);
if(a[i]<a[i-1]&&a[i]<a[i+1])
d[i][j][1]=d[i-1][j][0]+a[i];
else if(j)
d[i][j][1]=d[i-1][j-1][0]+min(a[i-1]-1,a[i+1]-1);
if(i==n)ans=max(ans,d[i][j][0]);
}
}
printf("%lld",ans);
}