专栏文章
题解:【NOIP2024模拟测试 #33】变幻
题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mir09smu
- 此快照首次捕获于
- 2025/12/04 13:38 3 个月前
- 此快照最后确认于
- 2025/12/04 13:38 3 个月前
题目描述
如果数组 中有任意一个点 满足 且 ,我们则称这个点 为“山谷点”。注意,数组中第一个元素和最后一个元素永远不可能为山谷点。
一个数组的价值是所有山谷点之和。至多修改 次数组,每次修改可以任选一个位置,使得这个位置上的数字变得比原来更小。你希望数组的价值最大,求最大价值。
输入格式
第一行包含两个正整数 和 ,意义如题面所示。
接下来一行包含 个正整数,表示数组中的元素 。
输出格式
输出一行一个正整数,表示答案。
题解
看到这道题,我们明显发现,是一个DP,我们用 表示状态, 表示考虑到前 个位置, 表示已经变换过 次, 表示这个位置有没有得分。
注意,不能用 表示有没有change,因为就算没有change,得分后也不能再改变下一个点。
那么,状态转移显然,详见代码,注意题目要求 ,记得 。
代码
CPP#include<bits/stdc++.h>
using namespace std;
long long n,k,a[2010],f[2010][2010][2],ans; // 0 - not point , 1 - is point
int main()
{
freopen("t1.in","r",stdin);
freopen("t1.out","w",stdout);
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
if(a[2]<a[1] && a[2]<a[3])
f[2][0][1] = a[2];
else
f[2][1][1] = min(a[1],a[3])-1 ;
for(int i=3;i<=n;i++)
{
for(int j=0;j<=k;j++)
{
if(a[i]<a[i-1] && a[i]<a[i+1])
f[i][j][1] = f[i-1][j][0] + a[i] ;
else if(j>=1)
f[i][j][1] = f[i-1][j-1][0] + min(a[i-1],a[i+1]) - 1 ;
f[i][j][0] = max(f[i-1][j][0],f[i-1][j][1]);
}
}
for(int i=0;i<=k;i++)
ans = max(ans,max(f[n][i][0],f[n][i][1]));
printf("%lld",ans);
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...